Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL是否每个查询/子查询只使用一个索引?_Mysql_Performance - Fatal编程技术网

MySQL是否每个查询/子查询只使用一个索引?

MySQL是否每个查询/子查询只使用一个索引?,mysql,performance,Mysql,Performance,请假设以下查询: select dic.*, d.syllable from dictionary dic join details d on d.word = dic.word 正如您所知(我也听说),MySQL在每个查询中只使用一个索引。现在我想知道,在上面的查询中,哪个索引会更好 字典(单词) 详细信息(word) 换句话说,当有一个连接(涉及两个表)时,哪个表的索引会受到影响?我是否应该同时创建这两个索引(在on子句上的列上),MySQL自己决定使用哪一个更好?MySQL将使用最

请假设以下查询:

select dic.*, d.syllable
from dictionary dic 
join details d on d.word = dic.word
正如您所知(我也听说),MySQL在每个查询中只使用一个索引。现在我想知道,在上面的查询中,哪个索引会更好

  • 字典(单词)
  • 详细信息(word)

换句话说,当有一个
连接
(涉及两个表)时,哪个表的索引会受到影响?我是否应该同时创建这两个索引(在
on
子句上的列上),MySQL自己决定使用哪一个更好?

MySQL将使用最有选择性的索引(给出最少行的索引)。这意味着它取决于数据,类似的优化也可能在数据库的不同版本之间发生变化

正如您所知(我也听说),MySQL在每个查询中只使用一个索引

通常,大多数数据库在每个表、每个查询中只使用一个索引。情况并非总是如此,但至少是一条不错的经验法则。对于您的特定示例,您可以依赖于此

现在我想知道,在上面的查询中,哪个索引会更好

您编写的查询实际上是一个内部联接。这意味着两个表中的任何一个都可能出现在联接的左侧,并且结果集在逻辑上是等价的。因此,MySQL可以自由地按照其选择的任何顺序编写连接。被选中的计划可能会将较大的表放在左侧,较小的表放在右侧。如果您知道表的实际执行顺序,那么只需为正确的表编制索引即可。鉴于您可能不知道这一点,那么您建议的两个指数都是合理的:

在字典(word)上创建索引dict_idx;
创建索引详细信息\u idx ON details(word);
我们甚至可以尝试通过覆盖select子句中出现的列来改进上述索引。例如,
details
上的索引可以扩展为:

创建索引细节\u idx关于细节(单词、音节);

这将允许MySQL专门使用上述索引来满足查询计划,而不需要返回原始表。您选择了
dictionary.*
,因此用一个索引来覆盖它可能是不可能的或不可取的,但至少这一点得到了理解。

MySQL将使用最具选择性的索引,这通常是不正确的。@Akina“从考虑中删除行。如果要在多个索引之间进行选择,MySQL通常会使用查找最少行数的索引”。最常见的例子是,存在选择性较低但覆盖索引的情况。这是对不同问题的回答(未被询问).参见Tim的答案-他建议通过
详细信息
表格创建覆盖索引,这对问题很有用。我怀疑这个问题不实用,OP只需要理论上的回答。还要注意你所说的词——“正常”但“不总是”通常,大多数数据库在每个表、每个查询中只使用一个索引。不是每个表,而是每个表副本。如果一个表在一个查询中被使用了两次或两次以上,那么每个副本可能会使用自己的索引,当然,这可能会有所不同。我认为,当没有任何矛盾时,优化器会从较小的表开始。在您的示例中,word似乎是两个表的主键。请为这两个表提供
SHOW CREATE table
。如果
word
是两个表的主键,为什么要有两个表而不是将它们组合起来??提供
EXPLAIN SELECT…
以进一步讨论问题。MySQL将对一个表进行表扫描,然后使用索引进入另一个表。在
位置添加一个
,将从根本上改变讨论!