聊一聊 InnoDB 引擎中的这些索引策略

在上一篇中,咱们简单的介绍了一下 InnoDB 引擎的索引类型,这一篇咱们继续学习 InnoDB 的索引,聊一聊索引策略,更好的利用好索引,提高数据库的性能,主要聊一聊覆盖索引、最左前缀原则、索引下推。java

覆盖索引

覆盖索引是指在普通索引树中能够获得查询的结果,不须要在回到主键索引树中再次搜索mysql

创建以下这张表来演示覆盖索引:sql

mysql> create table T ( ID int primary key, age int NOT NULL DEFAULT 0, name varchar(16) NOT NULL DEFAULT '', index age(age)) engine=InnoDB;
复制代码

咱们执行select * from T where age between 13 and 25 语句,这条语句的执行流程大概为:数据库

  • 一、在 age 索引树中查找到 age = 13 的记录,取得 ID 的值
  • 二、根据 id 的值在主键索引上查找所须要的全部信息
  • 三、在 age 树上往下取,重复 一、2 两步操做,直到 age 不符合条件为止。

若是咱们将语句换为 select ID from T where age between 13 and 25,执行这条语句时,在 age 索引树上就能够查询到 ID 的值,省去了上面的回表操做,这样就减小了搜索次数,提高了查询效率。微信

这时候的 age 索引树已经能够知足咱们的查询需求,age 索引就称为覆盖索引。性能

覆盖索引是经常使用的数据查询优化技术,能够极大的提高数据库性能,有如下几个缘由:学习

  • 减小树的搜索次数,显著提高查询性能
  • 索引是按照值的顺序存储,因此对于 I/O 密集型的范围查询比随机从磁盘中读取每一行的 I/O 要少不少
  • 索引的条目远小于数据的条目,在索引树上读取会极大的减少数据库的访问量

最左前缀原则

最左前缀原则是创建在联合索引之上的,若是咱们创建了联合索引,咱们不须要使用索引的所有定义,只要用到了索引中的最左边的那个字段就可使用这个索引,这就是 B-tree 索引支持最左前缀原则。优化

创建以下这张表来解释最左前缀原则:spa

mysql> create table T ( ID int primary key, age int NOT NULL DEFAULT 0, name varchar(16) NOT NULL DEFAULT '', ismale tinyint(1) DEFAULT NULL, email varchar(64), address varchar(255), KEY `name_age` (`name`,`age`)) engine=InnoDB;
复制代码

咱们创建了联合索引 name_age,如今,假设咱们有一下三种查询情景:code

  • 一、查出用户名的第一个字是“张”开头的人的年龄。即查询条件子句为"where name like '张%'"
  • 二、查处用户名中含有“张”字的人的年龄。即查询条件子句为"where name like '%张%'"
  • 三、查出用户名以“张”字结尾的人的年龄。即查询条件子句为"where name like '%张'"

在这三种状况中,第一种状况能够利用到 name_age 这个联合索引,加速查询,能够看出,咱们并无 使用索引的所有定义,只要知足最左前缀,就能够利用索引来加速检索。这个最左前缀能够是联合索引的最左 N 个字段,也能够是字符串索引的最左 M 个字符。

若是咱们将索引的顺序调整为KEYname_age(age,name) ,那么上面三种状况都使用不到这个联合索引。

维护索引须要代价,因此有时候咱们能够利用“最左前缀”原则减小索引数量

索引下推

索引下推优化是 MySQL 5.6 引入的, 能够在索引遍历过程当中,对索引中包含的字段先作判断,直接过滤掉不知足条件的记录,减小回表次数。

创建以下这张表来解释索引下推:

mysql> create table T ( ID int primary key, age int NOT NULL DEFAULT 0, name varchar(16) NOT NULL DEFAULT '', ismale tinyint(1) DEFAULT NULL, email varchar(64), address varchar(255), KEY `name_age` (`name`,`age`)) engine=InnoDB;
复制代码

在表中创建了 name、age 的联合索引,咱们执行 select * from T where name like '张%' and age=10 and ismale=1;语句,咱们已经知道了B-tree 索引的最左前缀原则,因此将会用到 name_age 索引,由于索引下推优化,会在 name_age 索引树上判断 name 和 age 是否知足

根据咱们上面的执行语句,会在 name_age 索引树上查找 name 以 '张' 开头的而且 age = 10 的数据,而后在回到主键索引树中查询所须要的信息,并非全部 name_age 索引树上查找 name 以 '张' 开头的数据都回主键索引树中查询数据,这样就减小了一些没必要要的查询。

假设咱们的数据以下图所示:

索引下推

在 name_age 索引树中有四条符合 name 以 '张'开头的数据,若是没有索引下推,则须要回到主键索引树上判断 age 是否等于 10 ,这样就须要回表四次,而有了索引下推以后,在 name_age 索引树上就判断 age 是否等于 10 ,只须要回表两次,这样就减小了回表次数,提高了查询性能。

以上就是关于 InnoDB 引擎中的索引策略,感谢您的阅读,但愿这篇文章对您的学习或者工做有所帮助。

最后

目前互联网上不少大佬都有 MySQL 相关文章,若有雷同,请多多包涵了。原创不易,码字不易,还但愿你们多多支持。若文中有所错误之处,还望提出,谢谢。

欢迎扫码关注微信公众号:「平头哥的技术博文」,和平头哥一块儿学习,一块儿进步。

平头哥的技术博文
相关文章
相关标签/搜索