昨天湖人惨败今天快船惨败,淦,下午跑来公司,在家效率属实低,计划赶不上变化快,昨晚计划理完发回来更文章结果被拦下做了个头发护理,当时也不知道他从哪看出来我是个程序员,这该死的气质,想起雷总说每个人头顶上都是一栋大别野,千万不能跟腿哥似的只剩个三室一厅了,做做吧...

倒腾了一个多小时我也没看出来有啥区别。理发师给做完跟我聊天的语气都变欢快了,社会是真的险恶,淦!我又被坑了!
上篇简单提了提InnoDB索引的数据结构模型,可以自行深入再了解一下,毕竟索引还是非常重要的,这篇就介绍一下索引的应用以及背后的实现逻辑,学会后可以帮助你合理的设计数据库索引,以及接口性能优化的时候多一个考虑项。首先提问一下,有这么一张表,建表语句如下。
mysql> create table T (ID int primary key,k int NOT NULL DEFAULT 0,s varchar(16) NOT NULL DEFAULT '',index k(k))engine=InnoDB;//插入数据insert into T values(100,1, 'aa'),(200,2,'bb'),(300,3,'cc'),(500,5,'ee'),(600,6,'ff'),(700,7,'gg');
那么select * from T where k between 3 and 5 这条语句要执行几次搜索操作?

首先建表的时候有一个index,所以会有一个k索引树,主键为主键索引生成一个主键树,where里以k为条件首先走k索引树。
1 通过k索引树找到k=3对应的主键ID为300
2 再到主键树通过ID找到R3
3 继续往下走下一个k=5,主键ID为500
4 主键找到R4
5 k索引树下一个k=6不满足条件退出
上篇提过通过普通索引树拿到key值回到主键树的过程就叫回表,那就很明显了,查找一行数据要找两次树,那找一次树肯定比两次快啊,有没有方法不回表查询呢
覆盖索引
想一下回表是为了干啥,为了取到k索引树没有但又需要的数据,那我们让k索引树上有需要的数据不就可以不去主键树上查询了。比如
select ID from T where k between 3 and 5
只查一个ID,而ID的值已经在k索引树上了,因此可以直接提供查询结果,不需要回表。也就是说,在这个查询里面,索引k已经“覆盖了”我们的查询需求,称为覆盖索引。
最左前缀原则
B+树这种索引结构,可以利用索引的“最左前缀”,来定位记录,假设有key(name,age),当你的逻辑需求是查到所有名字是“张三”的人时,可以快速定位到ID4,然后向后遍历得到所有需要的结果。如果你要查的是所有名字第一个字是“张”的人,SQL条件是"where name like ‘张%’"。这时,你也能够用上这个索引,查找到第一个符合条件的记录是ID3,然后向后遍历,直到不满足条件为止。
索引下推
当满足最左前缀原则的时候,最左前缀可以直接在索引中定位数据。那些不符合最左前缀的部分,会怎么样呢?还是以联合索引(name, age)为例。如果现在有一个需求:检索出表中“名字第一个字是张,而且年龄是10岁的所有男孩”。
mysql> select * from tuser where name like '张%' and age=10 and ismale=1;
这里说一个小技巧name = '张%'是可以走索引的,name = '%张%'就不走了,好的继续,首先name可以走联合索引,但是条件是like,这里like、大于、小于这种都不会往后走了,导致age扫描不到。只能用 “张”,找到第一个满足条件的记录ID3。然后咋整呢,回表呗。在MySQL 5.6之前,只能从ID3开始一个个回表,到主键索引上找出age、ismale对比字段值返回结果集。而MySQL 5.6 引入的索引下推优化(index condition pushdown), 可以在索引遍历过程中,对索引中包含的字段先做判断,直接过滤掉不满足条件的记录,减少回表次数。

无索引下推

有索引下推
也就是InnoDB在(name,age)索引内部就判断了age是否等于10,对于不等于10的记录,直接判断并跳过。
下期再见铁子们~




