序章
在数据库面试中,关于联合索引的考察点,总能引出诸多热议。特别是在深入讨论时,总会围绕一个核心话题——最左匹配原则。你是否能够自如地回答关于联合索引的相关问题呢?让我们一起探讨联合索引的奥秘。
什么是联合索引?
当我们基于多个字段创建一个索引时,我们称之为联合索引。例如,通过执行语句create index idx on table(A,B,C),我们在字段A、B、C上创建了一个联合索引。
联合索引的存储结构
在上一篇文章中,我们了解到索引的存储底层采用的是B+树结构。在InnoDB存储引擎中,主键索引的叶子节点存储的是数据本身,而非主键索引则存储的是主键id。那么,在联合索引的情况下,这个B+树是如何组织的呢?让我们通过一个具体的例子来深入探究。
假设我们创建了一个名为`user`的表,并添加了一些数据。这个表包含多个字段,如`id`(主键)、`age`、`money`、`ismale`和`name`。我们还为这个表创建了一个联合索引`index_bcd`,基于字段`age`和`money`。
在联合索引中,所有索引项都会出现在索引树上。存储引擎首先会根据第一个索引项进行排序,如果第一个索引项相同,才会去看第二个索引项。在查询时,如果第一个索引项没有被使用,那么联合索引就会失效。这是因为,在根节点上,存储引擎无法确定如何继续往下查找。
例如,当我们执行语句select from USER us where us.age=20 and us.money=30时,存储引擎会在根节点上根据age的范围进行查找,然后逐步深入到叶子节点,并获取对应的主键id。利用这个主键id回表查询所有的字段值。
这个过程展现了联合索引的查找机制以及最左匹配原则的重要性。通过理解这些概念,我们可以更有效地利用数据库索引,提高查询效率。最左前缀法则
当为多个列创建索引时,需遵循最左前缀法则。这意味着查询需要从索引的最左侧列开始,并且不能跳过索引中的任何列。以组合索引(age,money,name)为例,如果你执行如下查询:
`select from user where money=3 AND name='程序员fly'`
由于跳过了age这一列,最左前缀法则没有被满足,因此索引将不会生效。这种情况在面试中经常被提及,让我们通过几个例子来深入理解。
使用组合索引
1. `select from user where age>5`
2. `select from user where age=5 and money>3`
3. `select from user where age=5 and money=3 and name='程序员fly'`
索引失效
在某些查询条件下,索引可能不会被使用。例如:
1. `select from user where money>3` (跳过开头的age列)
2. `select from user where money>3 and name='程序员fly'` (同样跳过开头的age列)
使用部分索引
对于某些查询,如 `select from user where age>5 AND money=3`,范围查询只能使用到第一个列(age)。MySQL在5.6之后的版本,优化器可能会调整查询语句的顺序。例如,将上述查询调整为 `select from user where money=3 AND age>5`。这需要我们进一步研究和理解。
索引下推
当我们面对这样的查询需求:查询姓李的年龄为20周岁的男性用户的信息,我们可能会考虑建立(name,age)的联合索引。由于性别字段的区分度不高,可能不适合建立索引。例如:
`SELECT from user where name like '李%' and age=20 and ismale=0;`
在MySQL 5.6之前,没有索引下推的概念。而在MySQL 5.6及之后的版本中,引入了索引下推的优化。对于像 `name like '李%' and age=20` 这样的检索,MySQL 5.6版本之前会对匹配的数据进行回表查询。但5.6版本后,会先过滤掉不满足条件的记录(如age不等于20的数据),然后再进行回表查询,从而减少回表率,提高检索速度。这种优化提高了数据库的处理效率和性能。 |