如果你在面试中,听到MySQL5.6”、“索引优化” 之类的词语,你就要立马get到,这个问的是“索引下推”。

什么是索引下推

索引下推(Index Condition Pushdown,简称ICP),是MySQL5.6版本的新特性,它能减少回表查询次数,提高查询效率。

索引下推优化的原理

我们先简单了解一下MySQL大概的架构:

MySQL服务层负责SQL语法解析、生成执行计划等,并调用存储引擎层去执行数据的存储和检索。

索引下推下推其实就是指将部分上层(服务层)负责的事情,交给了下层(引擎层)去处理。

我们来具体看一下,在没有使用ICP的情况下,MySQL的查询:

  • 存储引擎读取索引记录;
  • 根据索引中的主键值,定位并读取完整的行记录;
  • 存储引擎把记录交给Server层去检测该记录是否满足WHERE条件。

使用ICP的情况下,查询过程:

  • 存储引擎读取索引记录(不是完整的行记录);
  • 判断WHERE条件部分能否用索引中的列来做检查,条件不满足,则处理下一行索引记录;
  • 条件满足,使用索引中的主键去定位并读取完整的行记录(就是所谓的回表);
  • 存储引擎把记录交给Server层,Server层检测该记录是否满足WHERE条件的其余部分。

索引下推的具体实践

理论比较抽象,我们来上一个实践。

使用一张用户表tuser,表里创建联合索引(name, age)。

如果现在有一个需求:检索出表中名字第一个字是张,而且年龄是10岁的所有用户。那么,SQL语句是这么写的:

select * from tuser where name like '张%' and age=10;

假如你了解索引最左匹配原则,那么就知道这个语句在搜索索引树的时候,只能用 ,找到的第一个满足条件的记录id为1。

那接下来的步骤是什么呢?

没有使用ICP

在MySQL 5.6之前,存储引擎根据通过联合索引找到name likelike '张%' 的主键id(1、4),逐一进行回表扫描,去聚簇索引找到完整的行记录,server层再对数据根据age=10进行筛选

我们看一下示意图:

可以看到需要回表两次,把我们联合索引的另一个字段age浪费了。

使用ICP

而MySQL 5.6 以后, 存储引擎根据(name,age)联合索引,找到name likelike '张%',由于联合索引中包含age列,所以存储引擎直接再联合索引里按照age=10过滤。按照过滤后的数据再一一进行回表扫描。

我们看一下示意图:

可以看到只回表了一次。

除此之外我们还可以看一下执行计划,看到Extra一列里 Using index condition,这就是用到了索引下推。

+----+-------------+-------+------------+-------+---------------+----------+---------+------+------+----------+-----------------------+
| id | select_type | table | partitions | type  | possible_keys | key      | key_len | ref  | rows | filtered | Extra                 |
+----+-------------+-------+------------+-------+---------------+----------+---------+------+------+----------+-----------------------+
|  1 | SIMPLE      | tuser | NULL       | range | na_index      | na_index | 102     | NULL |    2 |    25.00 | Using index condition |
+----+-------------+-------+------------+-------+---------------+----------+---------+------+------+----------+-----------------------+

索引下推使用条件

  • 只能用于range、 ref、 eq_refref_or_null访问方法;
  • 只能用于InnoDB和 MyISAM存储引擎及其分区表;
  • InnoDB存储引擎来说,索引下推只适用于二级索引(也叫辅助索引);

索引下推的目的是为了减少回表次数,也就是要减少IO操作。对于InnoDB聚簇索引来说,数据和索引是在一起的,不存在回表这一说。

  • 引用了子查询的条件不能下推;
  • 引用了存储函数的条件不能下推,因为存储引擎无法调用存储函数。

相关系统参数

索引条件下推默认是开启的,可以使用系统参数optimizer_switch来控制器是否开启。

查看默认状态:

复制代码

mysql> select @@optimizer_switch\G;
*************************** 1. row ***************************
@@optimizer_switch: index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on
1 row in set (0.00 sec)

切换状态:

set optimizer_switch="index_condition_pushdown=off";
set optimizer_switch="index_condition_pushdown=on";

五分钟搞懂MySQL索引下推相关推荐

  1. mysql decimal型转化为float_5分钟搞懂MySQL数据类型之数值型DECIMAL类型

    速成指南 5分钟搞懂MySQL数据类型 之数值型--DECIMAL类型 DECIMAL类型的语法:DECIMAL[(M[,D])] [UNSIGNED] [ZEROFILL].其中M指定的是数字的总位 ...

  2. 一文搞懂 MySQL 索引

    一文搞懂 MySQL 索引 1.MySQL 索引 简介 1.1.MySQL 索引 是什么?  索引是一个单独的.存储在 磁盘 上的 数据库结构 ,包含着对数据表里 所有记录的 引用指针. 1.2. M ...

  3. 五分钟搞懂什么是红黑树

    五分钟搞懂什么是红黑树(全程图解) 18-09-04 星925 + 关注 献花(2)  收藏 前戏 红黑树,对很多童鞋来说,是既熟悉又陌生.熟悉是因为在校学习期间,准备面试时,这是重点.然后经过多年的 ...

  4. ❤『知识集锦』一文搞懂mysql索引!!(建议收藏)

    作者:不吃西红柿 简介:CSDN博客专家.蓝桥签约作者.大数据领域优质创作者. 以我的资历和文凭,将来这个城市的大街,都归我扫.   [系列课程介绍] 『面试知识集锦』系列课程包括以下20个系列,超过 ...

  5. db2 删除索引_程序员必须了解的知识点——你搞懂mysql索引机制了吗?

    一.索引是什么 MySQL官方对索引的定义为:索引(Index)是帮助MySQL 高效 获取数据的数据结构,而MYSQL使用的数据结构是: B+树 在这里推荐大家看一本书, <深入理解计算机系统 ...

  6. 程序员必须了解的知识点——你搞懂mysql索引机制了吗?

    一.索引是什么 MySQL官方对索引的定义为:索引(Index)是帮助MySQL 高效 获取数据的数据结构,而MYSQL使用的数据结构是:B+树 在这里推荐大家看一本书,<深入理解计算机系统的书 ...

  7. 数据库索引结构(方法),一张图搞懂MySQL索引

    索引结构(方法) Hash索引 :对于每一行数据,存储引擎都会对所有的索引列的值计算一个哈希码存储在哈希表中.哈希索引只包含哈希值和行指针(指向实际的行数据),当有哈希冲突时,则会逐行比较符合查询条件 ...

  8. 五分钟搞懂什么是红黑树(全程图解)

    红黑树(又叫平衡二叉树),对很多童鞋来说,是既熟悉又陌生.熟悉是因为在校学习期间,准备面试时,这是重点.然后经过多年的荒废,如今已经忘记的差不多了.如果正在看文章的你,马上快要毕业,面临着找工作的压力 ...

  9. 五分钟搞懂Xen、KVM、Qemu间的关系和区别

    Aha,忽然发现我也是个标题党,十分钟搞定某某技能这种标题最吸引人了.当然我也不是华而不实,是不是干货,你读了才知道.话说,接触Xen这么久了,现在才花时间搞清楚这个问题,要不是需要给别人解释,还不知 ...

最新文章

  1. leetcode 21 Merge Two Sorted Lists
  2. python 关于排序的问题
  3. C/Cpp / 类中静态成员变量和普通成员变量的区别
  4. protobuf入门教程(三):常用序列化/反序列化接口
  5. leetcode1437. 是否所有 1 都至少相隔 k 个元素
  6. java实现对大文件切割下载_Java实现大文件的切割与合并操作示例
  7. 服务器主板稳定,服务器主板
  8. html循环查询的数据,SQL查询遍历数据方法一 [ 临时表 + While循环]
  9. TextView设置文字竖着排放
  10. transition的合理运用
  11. python 如何加密_Python如何玩转加密?
  12. Segger Embedded Studio使用有什么技巧?
  13. R在市场调查中的应用--探索性因子分析(EFA)
  14. Python入门教程(从小白到高级)(新版)
  15. C++开源项目:十行代码15个BUG,你入坑了吗?
  16. c语言程序负数,C语言中负数怎么表示的?
  17. 转(havel 算法)
  18. matlab编程入门实例,matlab编程实例100例
  19. 如何判断Android系统的版本
  20. 分享一个最近github上比较热门的javaScript-questions

热门文章

  1. 台式电脑可以连接手机热点吗_移动硬盘可以连接手机吗
  2. php视频文件上传到服务器,上传和下载图片和视频到服务器
  3. java整形怎么转字符串型_java整型与字符串互转
  4. python精要(71)-VMDK操作(1)
  5. go语言基础到提高(13)-同步
  6. tensorflow随笔-constant
  7. 21-5-22校赛J 下围棋
  8. 【机器学习】推荐一个好用的开源automl工具
  9. 【Python】在模仿中精进数据可视化09:近期基金涨幅排行可视化
  10. 【数学基础】从零构建统计随机变量生成器之离散基础篇