我正在考虑进行一些查询优化,并对有关多个索引的排序提出疑问。
我知道你可以在多个列上做索引,并且你必须将where子句的顺序与索引字段顺序相匹配。
我的问题是关于多字段索引中字段的排序。例如,如果我们有FirstName
和LastName
字段,并且我们假设LastName
比FirstName
更独特,那么在一个排序中执行索引是否有益于另一个?
E.g。预计(LastName, FirstName)
索引的效果会好于(FirstName, LastName)
的索引,反之亦然吗?
我从某人那里听说你想在你的where子句中首先做最缩小的项目,所以如果是这种情况,我会假设我们在索引中想要相同,但我想证实。
答案 0 :(得分:1)
WHERE
子句中的测试顺序无关紧要。如果您匹配索引中的两个列,它们在索引中的顺序也无关紧要。查询优化器将按索引顺序有效地连接两个字段,然后在一个步骤中在索引中查找该条目。
复合索引中列的顺序仅在匹配字段子集时才有意义。如果您正在搜索索引的某些前缀,仍可以使用该索引。例如。如果您执行(firstname, lastname)
,则可以使用WHERE firstname = 'John'
,但如果执行WHERE lastname = 'Smith'
,则可以使用{{1}}。有关详细信息,请参阅Does the order of columns matter in a multi-column index if there is no value in the WHERE clause。
答案 1 :(得分:0)
(简单地写评论的响应太多。)
WHERE lastname='Fangs' AND firstname='Venom'
- WHERE
和 INDEX
可以按任意顺序排列。我不同意关于基数的评论。在 this 的情况下,只关注组合的行数。无论如何,BTree钻取都是同样的努力。 (与需要检查的索引行数相比,比较的字节数较小。)
WHERE firstname LIKE 'V%' AND lastname = 'Fangs'
- INDEX(lastname, firstname)
是INDEX
的最佳订单。 (WHERE
中的顺序无关紧要)。请注意,'='首先是'range'(LIKE
)。
对于InnoDB(默认引擎),没有“哈希”索引选项。
如果您有INDEX(a,b,c)
,WHERE
提及(a
),或(a
和b
),或全部三个字段可以使用INDEX
。如果测试是在“=”和ANDed一起,可以使用该索引。
除了少数例外情况,索引中的 first 字段需要在WHERE中使用'='进行测试,然后一个更多字段可以是“范围”测试(与上面的LIKE示例一样)。
例如,WHERE firstname LIKE 'V%' AND lastname LIKE 'F%'
将仅使用任何索引的一个字段(第一个字段)。如果您同时拥有INDEX(lastname, firstname)
和INDEX(firstname, lastname)
,则基数很重要。
所有这些以及更多内容都在我的Cookbook on building the best INDEX from a SELECT。
中