MySql覆盖索引

mysql的innodb引擎通过搜索树方式实现索引,索引类型分为主键索引和二级索引(非主键索引),主键索引树中,叶子结点保存着主键即对应行的全部数据;而二级索引树中,叶子结点保存着索引值和主键值,当使用二级索引进行查询时,需要进行回表操作。

1.覆盖索引

CREATE TABLE `user_table` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `username` varchar(255) NOT NULL,
  `password` varchar(255) DEFAULT NULL,
  `age` int(11) unsigned Not NULL,
  PRIMARY KEY (`id`),
  key (`username`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8

语句A

select id from user_table where username = ‘xxx‘

执行该语句, 因为username索引上包含主键值所以直接返回

语句B

select password form user_table where username = ‘xxx‘

执行该语句,查询到username索引上的主键值, 然后再根据主键值回表查询出password。
由上可知当select的列和where的列都在索引上的时候就不需要进行回表操作。
所以我们可以新建username和password的联合索引增加查询效率。

2.联合索引

通俗理解:
利用索引中的附加列,您可以缩小搜索的范围,但使用一个具有两列的索引 不同于使用两个单独的索引。复合索引的结构与电话簿类似,人名由姓和名构成,电话簿首先按姓氏对进行排序,然后按名字对有相同姓氏的人进行排序。如果您知道姓,电话簿将非常有用;如果您知道姓和名,电话簿则更为有用,但如果您只知道名不姓,电话簿将没有用处。

所以说创建复合索引时,应该仔细考虑列的顺序。对索引中的所有列执行搜索或仅对前几列执行搜索时,复合索引非常有用;仅对后面的任意列执行搜索时,复合索引则没有用处。

最左前缀原则

以最左边的为起点任何连续的索引都能匹配上

联合索引本质:

当创建(a,b,c)联合索引时,相当于创建了(a)单列索引,(a,b)联合索引以及(a,b,c)联合索引
想要索引生效的话,只能使用 a和a,b和a,b,c三种组合;当然,我们上面测试过,a,c组合也可以,但实际上只用到了a的索引,c并没有用到!

2.索引下推

现有联合索引(username, age)
语句C

select * from user_table where username like ‘张%‘ and age > 10

我们判断有两种情况

  1. 先在索引中查询出以张开头的索引然后进行回表操作过滤出年龄大于10的数据
  2. 直接所以中查询出以张开头的和年龄大于10的索引在进行回表操作
    很明显第二种回表的数据更小,这就是索引下推
注意点

1.innodb引擎的表,索引下推只能用于二级索引。就像之前提到的,innodb的主键索引树叶子结点上保存的是全行数据,所以这个时候索引下推并不会起到减少查询全行数据。
2.索引下推一般可用于所求查询字段(select列)不是/不全是联合索引的字段,查询条件为多条件查询且查询条件子句(where/order by)字段全是联合索引。
假设表t有联合索引(a,b),下面语句可以使用索引下推提高效率

select * from t where a > 2 and b > 10;

MySql覆盖索引

上一篇:java基础- 你真的了解运算符吗?


下一篇:MongoDB数据库笔记