MySQL: 连接的 table 的两个字段都需要索引吗?

MySQL: does indices needed on both fields of table that are joined?

当我像这样执行 SQL 时;

SELECT * 
  FROM table_foo 
  JOIN table_bar
    ON table_foo.foo_id = table_bar.bar_id

我需要 table_foo.foo_id 上的索引吗?

或者 MySQL 在 table_foo.foo_idtable_bar.bar_id 上使用两个索引?

EXPLAIN的结果是这样的

这个查询有多个可能的执行计划:

SELECT f.*, b.* 
FROM table_foo f JOIN
     table_bar b
     ON f.foo_id = b.bar_id;

这里有一些例子:

  1. 您要避免(大概)的是嵌套循环连接,它循环遍历一个 table -- 逐行 -- 然后每一行循环遍历第二个。
  2. 扫描 foo 并使用 table_bar(bar_id) 上的索引查找 bar 中的每个值。从 bar 索引中的行 ID,获取每个匹配行的关联列。
  3. 扫描 bar 并使用 table_foo(foo_id) 上的索引查找 foo 中的每个值。从 foo 索引中的行 ID,获取每个匹配行的关联列。
  4. 使用合并连接扫描两个 索引,并在每个table 中查找关联的行。

这省去了其他选项,例如通常不会使用索引的散列连接。

因此,可以使用其中一个或两个索引,具体取决于优化器实现的算法。也就是说,一个索引通常足以获得您想要的性能。但是,如果您在两个 table 上都有索引,则可以为优化器提供更多选项。