我有以下覆盖索引:
INDEX (col1, col3); -- index 1
INDEX (col1, col2, col3); -- index 2
Run Code Online (Sandbox Code Playgroud)
因为我想支持以下类型的查询:
1)
SELECT col3
FROM my_table
WHERE col1 = ... AND
col2 = ...
ORDER BY col3
Run Code Online (Sandbox Code Playgroud)
2)
SELECT col3
FROM my_table
WHERE col1 = ...
ORDER BY col3
Run Code Online (Sandbox Code Playgroud)
我不熟悉覆盖索引的工作原理。索引1是多余的吗?或者覆盖索引是否要求列并排?
“覆盖”这个词一开始就是错误的。我稍后会回到这个话题。
查询的最佳索引可以总结为:
=
列WHERE
。ORDER BY
相同顺序的列,并且可以是 allASC
或 all DESC
。(MySQL 8.0 这里有一个例外。)您的索引 1 对于查询 2 来说是必要且充分的。
您的索引 2 对于查询 1 来说是必要且充分的。
任何不同的情况都将是次优的。
请注意,它们也将是“覆盖”的,因为其中任何位置的所有列都SELECT
可以在相应的索引中找到。
索引 2“覆盖”了两个查询,但对于查询 2 来说并不是很好。
INDEX(a), INDEX(a,b)
,丢弃前者。有关这些提示以及更多信息,请参阅http://mysql.rjweb.org/doc.php/index_cookbook_mysql
这是“覆盖”,但效率不高,因为col99
在索引中第一个,但不用于过滤或排序:
INDEX(col99, col1, col2, col3)
Run Code Online (Sandbox Code Playgroud)
它可能会被使用,但只是因为它具有覆盖性。它不能用于过滤或排序。
这是“覆盖”,可用于避免排序,因为ORDER BY
列在前面:
INDEX(col3, col2, col1)
Run Code Online (Sandbox Code Playgroud)
无论各个列的基数如何,查询 1 都会对此感到满意:
INDEX(col2, col1, col3)
Run Code Online (Sandbox Code Playgroud)
回到标题问题:
覆盖索引中的列顺序重要吗?
回答:
打个比方
B+树有两个重要的属性: