1

请假设以下查询:

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

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

  • dictionary(word)
  • details(word)

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

4

2 回答 2

3

如您所知(我听说过),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.*,因此使用单个索引覆盖它可能是不可能或不可取的,但至少这可以理解。

于 2020-12-23T06:06:38.923 回答
1

MySQL 将使用最具选择性的索引(提供最少行的索引)。这意味着它取决于数据,并且像这样的优化可能会在数据库版本之间发生变化。

于 2020-12-23T06:05:12.677 回答