通过多场索引查询性能排序增益

时间:2015-04-10 22:53:55

标签: mysql optimization indexing query-optimization

我正在考虑进行一些查询优化,并对有关多个索引的排序提出疑问。

我知道你可以在多个列上做索引,并且你必须将where子句的顺序与索引字段顺序相匹配。

我的问题是关于多字段索引中字段的排序。例如,如果我们有FirstNameLastName字段,并且我们假设LastNameFirstName更独特,那么在一个排序中执行索引是否有益于另一个?

E.g。预计(LastName, FirstName)索引的效果会好于(FirstName, LastName)的索引,反之亦然吗?

我从某人那里听说你想在你的where子句中首先做最缩小的项目,所以如果是这种情况,我会假设我们在索引中想要相同,但我想证实。

2 个答案:

答案 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),或(ab),或全部三个字段可以使用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