IndexConditionPushdown(索引条件下推)ICP是Mysql5.6之后新增的功能。主要核心点是将数据过滤过程放在存储引擎层,而不是像以前一样放在服务器层进行过滤。虽然这是一个比较简单的概念,但是很多粗心的同学可能对索引下推有一个小小的误解。至于是什么,请看下文。什么是索引下推首先我们创建一张user表,创建age_name的联合索引,同时插入3条测试数据。然后,我们执行queryexplainSELECT*fromuserwhereage>10andname='a',如下图,你会看到Extra中显示了Usingindex条件,你可能知道,这意味着指数被向下推高。没错,这个查询场景就是索引下推,那么索引下推到底是什么?根据我们上面的场景,其实有两棵索引树,一个是主键索引,里面存放的是具体的数据信息,另外一个是age_name的联合索引,里面存放的是主键的ID。当没有ICP索引下推时,查询过程应该是这样的(忽略无关细节):MysqlServer层调用API查询存储引擎。数据存储引擎首先根据联合索引找到所有age>10的数据。每条数据根据主键索引向表中查询,直到找到不合格的结果,返回数据给server层。服务器根据条件过滤结果。流程结束后,ICP后流程如下:MysqlServer层调用API查询存储引擎数据存储引擎首先根据联合索引通过条件查找所有age>10的数据,根据已有name数据进行过滤在联合索引中,查找满足条件的数据。对于server层来说,进程结束后,比较两个进程就会很明显。使用ICP后,我们直接过滤联合索引中已有的数据即可,不需要找一堆没用的数据发给服务器。这样,减少了回表的次数和返回的数据,减少了IO次数,大大提高了性能。根据官方文档,ICP其实是有一定的使用限制场景的,只提到关键的,不提乱七八糟的。首先,ICP适用于range、ref、eq_ref、ref_or_null场景。InnoDB和MyISAM都支持ICP,也可以使用Mysql分区表。对于InndoDB,ICP只支持二级索引,因为不能使用主键索引。是吗?子查询不支持我们现在基本使用的5.6以上的版本。ICP默认开启。如果要关闭它,可以使用命令SEToptimizer_switch='index_condition_pushdown=off';。一个小误区一般来说,正常情况下,Mysql一次查询只能使用一个索引。我们修改一下上面的表结构,把联合索引改成两个单独的索引。数据保持不变,然后我们执行查询explainSELECT*fromuserwhereage>10andnamelike'a%',结果如下图。你会发现,妈的,为什么还有指数下推?这不科学吧?似乎无法解释。可不可以在这次下推index的时候,先查出age,再下推到nameindex呢?这是完全没有道理的。.其实真实的情况是,Usingindexcondition并不一定是用了indexpushdown,而是可以用,但不一定用。..这有点坑爹,在我们判断的时候可能会造成误会。如果你去网上找了很多人家这样建索引的例子,然后告诉你这是索引下推的时候,你想喷他就喷他。我们说索引下推一定是在联合索引的情况下,根据联合索引本身你需要很清楚现有的数据可以直接过滤一次,而不是返回到server层进行多次无用的回报过滤。好了,今天的话题到此结束,我是艾小娴,下期见。(本来想再画两张图的,但是好像这个概念太简单了,花里胡哨的图也没什么意义,就像你说的覆盖索引返回表画几张图给你解释一下,没必要吧?绝对不是因为我懒……)
