在MySQL的索引优化中,不仅存在单个字段的索引,根据业务的不同,联合索引也是非常常见的情况。

例如以下SQL

select * from users where gender = '男' and age between 18 and 20

我们希望在users表中查询性别为男,年龄基于18-20之间的用户,单纯的建立gender和age字段的索引显然是不足以满足我们的要求的,因为最终会被使用的索引只有一个[本例中,由于gender实际上是可以枚举的值,所以实际上并不适合做索引,这里只是做了一个示例]。

此时我们需要建立联合索引

ALTER TABLE users ADD INDEX users_age_gender (gender,age)

那么问题来了,在单独的搜索条件下,如单独按照age搜索和按照gender搜索,我们还需要再单独建立对应字段的索引吗?

答案是:gender不用,age用。

问题的答案其实就是MySQL索引的最左匹配原则。我们可以联系MySQL索引定义一文来综合理解MySQL最左匹配原则。简单来说,最左匹配原则就是,从联合索引的最左侧开始匹配,当满足了最左侧的查询结果,再进行下一个字段的查询匹配,直到所有的字段匹配结束。

回到之前的SQL,当我们建立了一个(gender,age)的联合索引,该索引树就会先按照gender进行排序,相同的gender又会按照age继续进行排序,直到一个索引树完全建立完成,在查询时,首先查找gender为'男'的区间,在该区间中继续按照age进行筛查,直到筛查出所有结果,那么可想而知,只要查询条件中使用了gender,该索引就一定会被列入到备选使用索引中[虽然并不一定会使用],而如果我们按照age进行查询,由于该联合索引无法首先利用gender进行排序,所以无法应用于age字段的查询上,那么我们就需要重新建立一个以age为主导的单列索引或联合索引。