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_id
和 table_bar.bar_id
上使用两个索引?
EXPLAIN
的结果是这样的
这个查询有多个可能的执行计划:
SELECT f.*, b.*
FROM table_foo f JOIN
table_bar b
ON f.foo_id = b.bar_id;
这里有一些例子:
- 您要避免(大概)的是嵌套循环连接,它循环遍历一个 table -- 逐行 -- 然后每一行循环遍历第二个。
- 扫描
foo
并使用 table_bar(bar_id)
上的索引查找 bar
中的每个值。从 bar
索引中的行 ID,获取每个匹配行的关联列。
- 扫描
bar
并使用 table_foo(foo_id)
上的索引查找 foo
中的每个值。从 foo
索引中的行 ID,获取每个匹配行的关联列。
- 使用合并连接扫描两个 索引,并在每个table 中查找关联的行。
这省去了其他选项,例如通常不会使用索引的散列连接。
因此,可以使用其中一个或两个索引,具体取决于优化器实现的算法。也就是说,一个索引通常足以获得您想要的性能。但是,如果您在两个 table 上都有索引,则可以为优化器提供更多选项。
当我像这样执行 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_id
和 table_bar.bar_id
上使用两个索引?
EXPLAIN
的结果是这样的
这个查询有多个可能的执行计划:
SELECT f.*, b.*
FROM table_foo f JOIN
table_bar b
ON f.foo_id = b.bar_id;
这里有一些例子:
- 您要避免(大概)的是嵌套循环连接,它循环遍历一个 table -- 逐行 -- 然后每一行循环遍历第二个。
- 扫描
foo
并使用table_bar(bar_id)
上的索引查找bar
中的每个值。从bar
索引中的行 ID,获取每个匹配行的关联列。 - 扫描
bar
并使用table_foo(foo_id)
上的索引查找foo
中的每个值。从foo
索引中的行 ID,获取每个匹配行的关联列。 - 使用合并连接扫描两个 索引,并在每个table 中查找关联的行。
这省去了其他选项,例如通常不会使用索引的散列连接。
因此,可以使用其中一个或两个索引,具体取决于优化器实现的算法。也就是说,一个索引通常足以获得您想要的性能。但是,如果您在两个 table 上都有索引,则可以为优化器提供更多选项。