问题描述
我已经读过,在复合索引中,您应该首先对最具体的列进行排序,但是我的想法是,由于我的理解(或缺乏),最佳路线是首先覆盖最不具体的索引of) 关于索引映射如何在内存中工作。 visual aid
例如,如果我有一个表,vehicles
包含三列,vehicle
、type
和 driver
。
vehicle
可以过滤为 3 个可能的值 car
、bike
、helicopter
type
可以过滤为 6 个值,petrol/automatic
、petrol/manual
、diesel/automatic
、diesel/manual
、electric/automatic
、{{1} }
electric/manual
是驱动程序的名称(不确定数量的值)
--
如果按 driver
过滤可以返回 1000 个结果,按 vehicle
500 个结果,按 type
说,3 个结果,那么最佳索引不应该是 driver
吗?因为如果索引以 vehicle,type,driver
开头是不是意味着在进一步过滤之前扫描一个巨大的索引 driver
然后 type
?
有人可以帮我解决这个问题,并向我解释一下,如果我应该对最具体的列进行排序,为什么以及它是如何工作的?
解决方法
- 测试
=
的所有 3 列时,它们在INDEX
或WHERE
子句中的顺序无关。立> - 在测试某些列的
=
和一些具有范围(LIKE
、BETWEEN
等)的列时,将=
列放在INDEX
的前面。索引不会在第一个范围之外使用。 - 在测试 1 或 2 列时,这些列需要放在第一位。
由于这些准则,您可能会发现不同的查询需要不同的 INDEXes
。
更多:http://mysql.rjweb.org/doc.php/index_cookbook_mysql
和Higher cardinality column first in an index when involving a range?
查看基数的另一种方式是它仅适用于整个索引,而不适用于单个列。选择性差会导致优化器不使用索引,而是扫描表。
如果按车辆过滤可以返回1000个结果,按类型500个结果,按司机说3个结果
WHERE vehicle = '...' -- no index will be used
WHERE type = '...' -- no index will be used
WHERE driver = '...' -- INDEX(driver,...) will be used
(假设 WHERE
中没有其他相关内容。)
为此
WHERE vehicle = '...'
AND type = '...'
AND driver = '...'
这非常有用:INDEX(vehicle,type,driver)
。此外,WHERE
子句和 INDEX
的顺序可以不同。