索引下推,这个点你肯定不知道!

沙海 2021年9月3日01:24:56Java评论31字数 1838阅读6分7秒阅读模式
摘要

智能摘要

智能摘要文章源自JAVA秀-https://www.javaxiu.com/43738.html

是Mysql5.6之后新增的功能,主要的核心点就在于把数据筛选的过程放在了存储引擎层去处理,而不是像之前一样放到Server层去做过滤。我们创建一张user表,同时建立age_name的联合索引,同时插入3条测试数据。按照官方文档所说,ICP其实也存在一定的使用限制场景,只说关键的,乱七八糟的不说。对于InndoDB而言,ICP只支持二级索引,因为主键索引它用不上不是吗?其实不然,真实的情况是,Using index condition并不代表一定是使用了索引下推,只是代表可以使用,但是不一定用了。。。文章源自JAVA秀-https://www.javaxiu.com/43738.html

原文约 1079 | 图片 7 | 建议阅读 3 分钟 | 评价反馈文章源自JAVA秀-https://www.javaxiu.com/43738.html

索引下推,这个点你肯定不知道!

三太子敖丙 文章源自JAVA秀-https://www.javaxiu.com/43738.html

以下文章来源于艾小仙,作者艾小仙文章源自JAVA秀-https://www.javaxiu.com/43738.html

文章源自JAVA秀-https://www.javaxiu.com/43738.html

索引下推,这个点你肯定不知道!文章源自JAVA秀-https://www.javaxiu.com/43738.html

艾小仙.文章源自JAVA秀-https://www.javaxiu.com/43738.html

一个愤世嫉俗,脱离低级趣味的人文章源自JAVA秀-https://www.javaxiu.com/43738.html

文章源自JAVA秀-https://www.javaxiu.com/43738.html

索引下推,这个点你肯定不知道!文章源自JAVA秀-https://www.javaxiu.com/43738.html

索引下推(Index Condition Pushdown) ICP 是Mysql5.6之后新增的功能,主要的核心点就在于把数据筛选的过程放在了存储引擎层去处理,而不是像之前一样放到Server层去做过滤。文章源自JAVA秀-https://www.javaxiu.com/43738.html

虽然这是一个比较简单的概念,但是可能很多不细心的同学对于索引下推会存在一个小小的误区,至于是什么,请看下文。文章源自JAVA秀-https://www.javaxiu.com/43738.html

什么是索引下推

首先,我们创建一张user表,同时建立age_name的联合索引,同时插入3条测试数据。文章源自JAVA秀-https://www.javaxiu.com/43738.html

索引下推,这个点你肯定不知道!文章源自JAVA秀-https://www.javaxiu.com/43738.html

然后,我们执行查询explain SELECT * from user where age >10 and name = 'a',如下图所示,就会看见Extra中显示了Using index condition,你可能就知道了,这表示出现了索引下推了。文章源自JAVA秀-https://www.javaxiu.com/43738.html

索引下推,这个点你肯定不知道!文章源自JAVA秀-https://www.javaxiu.com/43738.html

没错,针对这个查询场景就是索引下推,那到底什么是索引下推呢?文章源自JAVA秀-https://www.javaxiu.com/43738.html

按照我们上述的场景,实际上就存在两个索引树,一个是主键索引,存储了具体的数据的信息,另外则是age_name的联合索引,保存了主键的ID。文章源自JAVA秀-https://www.javaxiu.com/43738.html

索引下推,这个点你肯定不知道!文章源自JAVA秀-https://www.javaxiu.com/43738.html

在没有ICP索引下推的时候,这个查询的流程应该是这样(略过无关的细节):文章源自JAVA秀-https://www.javaxiu.com/43738.html

  1. Mysql Server层调用API查询存储引擎数据文章源自JAVA秀-https://www.javaxiu.com/43738.html

  2. 存储引擎根据联合索引首先通过条件找到所有age>10的数据文章源自JAVA秀-https://www.javaxiu.com/43738.html

  3. 找到的每一条数据都根据主键索引进行回表查询,直到找到不符合条件的结果文章源自JAVA秀-https://www.javaxiu.com/43738.html

  4. 返回数据给Server层,Server根据条件对结果进行过滤,流程结束文章源自JAVA秀-https://www.javaxiu.com/43738.html

而有了ICP之后的流程则是这样:文章源自JAVA秀-https://www.javaxiu.com/43738.html

  1. Mysql Server层调用API查询存储引擎数据文章源自JAVA秀-https://www.javaxiu.com/43738.html

  2. 存储引擎根据联合索引首先通过条件找到所有age>10的数据,根据联合索引中已经存在的name数据进行过滤,找到符合条件的数据文章源自JAVA秀-https://www.javaxiu.com/43738.html

  3. 根据找到符合条件的数据,回表查询文章源自JAVA秀-https://www.javaxiu.com/43738.html

  4. 返回数据给Server层,流程结束文章源自JAVA秀-https://www.javaxiu.com/43738.html

对比这两个流程就会很明显的发现,使用ICP之后我们就是简单的通过联合索引中本来就有的数据直接过滤了,不需要再查到一堆无用的数据去Server层进行过滤,这样的话减少了回表的次数和返回的数据,IO次数减少了,对性能有很好的提升。文章源自JAVA秀-https://www.javaxiu.com/43738.html

按照官方文档所说,ICP其实也存在一定的使用限制场景,只说关键的,乱七八糟的不说。文章源自JAVA秀-https://www.javaxiu.com/43738.html

  1. 首先,ICP适用于range、ref、eq_ref和ref_or_null的场景下文章源自JAVA秀-https://www.javaxiu.com/43738.html

  2. InnoDB和MyISAM都支持ICP,Mysql partition分表的话也可以使用文章源自JAVA秀-https://www.javaxiu.com/43738.html

  3. 对于InndoDB而言,ICP只支持二级索引,因为主键索引它用不上不是吗?文章源自JAVA秀-https://www.javaxiu.com/43738.html

  4. 子查询不支持文章源自JAVA秀-https://www.javaxiu.com/43738.html

现在我们基本都使用的5.6以上的版本了,默认就是开启ICP的,想关闭的话可以通过命令SET optimizer_switch = 'index_condition_pushdown=off';文章源自JAVA秀-https://www.javaxiu.com/43738.html

一个小小的误区

一般来说,正常情况下Mysql一次查询都只能走一个索引,我们来修改上述的表结构,把联合索引改为两个单独的索引,数据保持不变文章源自JAVA秀-https://www.javaxiu.com/43738.html

索引下推,这个点你肯定不知道!文章源自JAVA秀-https://www.javaxiu.com/43738.html

然后我们执行查询explain SELECT * from user where age >10 and name like 'a%',结果如下图。文章源自JAVA秀-https://www.javaxiu.com/43738.html

索引下推,这个点你肯定不知道!文章源自JAVA秀-https://www.javaxiu.com/43738.html

你会发现,我靠,怎么还有索引下推?这不科学对不对,好像无法解释嘛,难道这一次索引下推还能先查出age再下推到name索引吗,这完全不合理啊。文章源自JAVA秀-https://www.javaxiu.com/43738.html

其实不然,真实的情况是,Using index condition并不代表一定是使用了索引下推,只是代表可以使用,但是不一定用了。。。文章源自JAVA秀-https://www.javaxiu.com/43738.html

这个就有点坑爹,可能会对我们判断的时候造成误解啊。文章源自JAVA秀-https://www.javaxiu.com/43738.html

如果你去网上搜很多人举例子这样建索引,然后告诉你这就是索引下推的时候,你可以尽情的喷他了,我们说索引下推一定是在联合索引的情况下,根据联合索引本身就有的数据直接做一次过滤,而不用再进行多次无用的回表再到Server层进行过滤,这一点你要很明确才行。文章源自JAVA秀-https://www.javaxiu.com/43738.html

文章源自JAVA秀-https://www.javaxiu.com/43738.html

继续阅读
速蛙云 - 极致体验,强烈推荐!!!购买套餐就免费送各大视频网站会员!快速稳定、独家福利社、流媒体稳定解锁!速度快,全球上网、视频、游戏加速、独立IP均支持!基础套餐性价比很高!这里不多说,我一直正在使用,推荐购买:https://www.javaxiu.com/59919.html
weinxin
资源分享QQ群
本站是JAVA秀团队的技术分享社区, 会经常分享资源和教程; 分享的时代, 请别再沉默!
沙海
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定