在看高性能mysql的时候,看到一段关于mysql5.6的索引条件推送的一段话。
来自于5.3.6 索引覆盖
image.png大概的意思是:没有ICP(index condition pushdown)前,过滤条件是传输不到存储引擎层的,过滤条件只在服务器层发生作用,服务器层只是从存储引擎中取索引,然后在服务层where过滤,然后再从存储引擎中取索引,如此循环,直到取到数据。(服务层取到的数据是放在内存,然后where操作也是在内存进行,所以说,索引小,能够节省内存)
有了ICP,则直接把索引过滤条件,发送到存储引擎,存储引擎直接返回过滤后的数据,服务层不需要再进行过滤了。
但是:
1、ICP只能用于二级索引。(做过测试聚簇索引没有ICP)
2、explain显示的执行计划中type值(join 类型)为range、 ref、 eq_ref或者ref_or_null。且查询需要访问表的整行数据,即不能直接通过二级索引的元组数据获得查询结果(索引覆盖)。(做过测试覆盖索引没有ICP )
做个测试:
mysql 版本5.7
开启ICP:
image.png
Using index condition说明使用了ICP
image.png
如果不开启ICP,则执行计划为如下,extra里显示服务层使用了where过滤
image.png
并且,开启了ICP,
执行这条select语句,不会锁住title <> ‘’的这条记录,如果不开启ICP,则会使用锁住title <> 的这条记录。
堵塞了:
image.png
原因是,不开启的时候,执行计划显示,存储引擎执行的type为range,范围查询,所以存储引擎锁住的只是title > 和 title < 的范围,而<>是服务层做的,所以<>也在这个范围内,被锁住了。
而如果开启了ICP,则服务层没有做where过滤,存储引擎做了,所以没有锁<>跳的这条记录。
高性能mysql这么解释(来自于5.3.11索引和锁):
image.png
网友评论