本文已参与「新人创作礼」活动,一起开启掘金创作之路。
哪些情况下索引会失效?
1、联合索引
联合索引的排序是先按照第一个字段排序,再按照第二个字段排序,...。
使用联合索引查询时,先通过二分查找查询第一个字段,再通过二分查找查询第二个字段,...。
最左前缀原则 (多列索引col1、col2和col3,索引生效 col1或col1,col2或col1,col2,col3)
如下情况联合索引失效:
(1)不满足最左前缀原则:无法再通过二分查找找到第一个字段;
(2)第一个字段使用了 != > < 等运算符,会失效,如 where a>1 and b==2;
2、LIKE语句中“ %(表示任意个字符) ”开头的;OR语句前后没有同时使用索引;
3、使用!=、<、>操作符查询;对字段进行null值判断;
4、如果估计全表扫描比使用索引快,则不使用索引(比如非常小的表,或索引密度太小,如性别字段)
索引下推
- 索引下推(index condition pushdown )简称ICP,在Mysql5.6版推出,用于优化查询。
- 在不使用ICP的情况下,如果存在多个索引列作为判断条件时,MySQL服务器将第一个索引键值传递给存储引擎,存储引擎把满足索引键值的记录全部取出,返回给服务器,然后由服务器判断数据是否符合其他条件
- 在使用ICP的情况下,如果存在多个索引列作为判断条件时,MySQL服务器将所有判断条件传递给存储引擎,然后存储引擎层会使用所有条件对记录进行过滤,将结果返回给MySQL服务器。
总结:技术关键在于将与索引相关的查询条件由服务器向下传递至存储引擎,有效减少MySQL 服务器访问存储引擎的次数,以及存储引擎访问基表的次数 ,大大提升查询的效率。
不使用ICP
MySQL 存储引擎层只把满足索引键值对应的整行表记录全部取出,并且上传给 MySQL 服务层。
MySQL 服务层对接收到的数据,使用 SQL 语句后面的 where 条件过滤,直到处理完最后一行记录,再一起返回给客户端。
使用ICP
MySQL 存储引擎层会使用包含索引键的其他过滤条件进行过滤,之后规避掉不满足的索引记录,只根据满足条件的索引记录回表取回数据上传到 MySQL 服务层。
MySQL 服务层对接收到的数据,使用 where 子句中不包含索引列的过滤条件做最后的过滤,然后返回数据给客户端。