首页 > 解决方案 > MySQL 每个查询/子查询是否只使用一个索引?

问题描述

请假设以下查询:

select dic.*, d.syllable
from dictionary dic 
join details d on d.word = dic.word

如您所知(我听说过),MySQL 每个查询只使用一个索引。现在我想知道,在上面的查询中,哪个索引会更好?

换句话说,当有一个join(涉及两个表)时,哪个索引会受到影响?我是否应该同时创建它们(在on子句的列上)并且 MySQL 本身决定使用哪个更好?

标签: mysqlperformance

解决方案


如您所知(我听说过),MySQL 每个查询只使用一个索引。

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

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

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

CREATE INDEX dict_idx ON dictionary (word);
CREATE INDEX details_idx ON details (word);

我们甚至可以尝试通过覆盖出现在 select 子句中的列来改进上述索引。例如,索引 ondetails可以扩展为:

CREATE INDEX details_idx ON details (word, syllable);

这将让 MySQL 专门使用上述索引来满足查询计划,而无需回溯到原始表。您选择dictionary.*,因此使用单个索引覆盖它可能是不可能或不可取的,但至少这可以理解。


推荐阅读