前面已经讲了MySQL的其他查询性能优化方式,没看过可以去了解一下:

MySQL查询性能优化七种武器之索引潜水

MySQL查询性能优化七种武器之链路追踪

今天要讲的是MySQL的另一种查询性能优化方式 — 索引下推(Index Condition Pushdown,简称ICP),是MySQL5.6版本增加的特性。

1. 索引下推的作用

主要作用有两个:

  1. 减少回表查询的次数
  2. 减少存储引擎和MySQL Server层的数据传输量

总之就是了提升MySQL查询性能。

2. 案例实践

创建一张用户表,造点数据验证一下:

CREATE TABLE `user` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
`name` varchar(100) NOT NULL COMMENT '姓名',
`age` tinyint NOT NULL COMMENT '年龄',
`gender` tinyint NOT NULL COMMENT '性别',
PRIMARY KEY (`id`),
KEY `idx_name_age` (`name`,`age`)
) ENGINE=InnoDB COMMENT='用户表';

在 姓名和年龄 (name,age) 两个字段上创建联合索引。

查询SQL执行计划,验证一下是否用到索引下推

explain select * from user where name='一灯' and age>2;

执行计划中的Extra列显示了Using index condition,表示用到了索引下推的优化逻辑。

3. 索引下推配置

查看索引下推的配置:

show variables like '%optimizer_switch%';

如果输出结果中,显示 index_condition_pushdown=on,表示开启了索引下推

也可以手动开启索引下推

set optimizer_switch="index_condition_pushdown=on";

关闭索引下推

set optimizer_switch="index_condition_pushdown=off";

4. 索引下推原理剖析

索引下推在底层到底是怎么实现的?

是怎么减少了回表的次数?

又减少了存储引擎和MySQL Server层的数据传输量?

在没有使用索引下推的情况,查询过程是这样的:

  1. 存储引擎根据where条件中name索引字段,找到符合条件的3个主键ID
  2. 然后二次回表查询,根据这3个主键ID去主键索引上找到3个整行记录
  3. 把数据返回给MySQL Server层,再根据where中age条件,筛选出符合要求的一行记录
  4. 返回给客户端

画两张图,就一目了然了。

下面这张图是回表查询的过程:

  1. 先在联合索引上找到name=‘一灯’的3个主键ID
  2. 再根据查到3个主键ID,去主键索引上找到3行记录

下面这张图是存储引擎返回给MySQL Server端的处理过程:

我们再看一下在使用索引下推的情况,查询过程是这样的:

  1. 存储引擎根据where条件中name索引字段,找到符合条件的3行记录,再用age条件筛选出符合条件一个主键ID
  2. 然后二次回表查询,根据这一个主键ID去主键索引上找到该整行记录
  3. 把数据返回给MySQL Server层
  4. 返回给客户端

现在是不是理解了索引下推的两个作用:

  1. 减少回表查询的次数
  2. 减少存储引擎和MySQL Server层的数据传输量

索引下推的含义就是,本来在MySQL Server层做的筛选操作,下推到存储引擎层来做。

5. 索引下推应用范围

  1. 适用于InnoDB 引擎和 MyISAM 引擎的查询
  2. 适用于执行计划是range, ref, eq_ref, ref_or_null的范围查询
  3. 对于InnoDB表,仅用于非聚簇索引。索引下推的目标是减少全行读取次数,从而减少 I/O 操作。对于 InnoDB聚集索引,完整的记录已经读入InnoDB 缓冲区。在这种情况下使用索引下推 不会减少 I/O。
  4. 子查询不能使用索引下推
  5. 存储过程不能使用索引下推

再附一张Explain执行计划详解图:

MySQL查询性能优化七种武器之索引下推的更多相关文章

  1. MySQL查询性能优化七种武器之索引潜水

    有读者可能会一脸懵逼? 啥是索引潜水? 你给起的名字的吗?有没有索引蛙泳? 这个名字还真不是我起的,今天要讲的知识点就叫索引潜水(Index dive). 先要从一件怪事说起: 我先造点数据复现一下问 ...

  2. MySQL查询性能优化七种武器之链路追踪

    MySQL优化器可以生成Explain执行计划,我们可以通过执行计划查看是否使用了索引,使用了哪种索引? 但是到底为什么会使用这个索引,我们却无从得知. 好在MySQL提供了一个好用的工具 - opt ...

  3. MySQL查询性能优化(精)

    MySQL查询性能优化 MySQL查询性能的优化涉及多个方面,其中包括库表结构.建立合理的索引.设计合理的查询.库表结构包括如何设计表之间的关联.表字段的数据类型等.这需要依据具体的场景进行设计.如下 ...

  4. 170727、MySQL查询性能优化

    MySQL查询性能优化 MySQL查询性能的优化涉及多个方面,其中包括库表结构.建立合理的索引.设计合理的查询.库表结构包括如何设计表之间的关联.表字段的数据类型等.这需要依据具体的场景进行设计.如下 ...

  5. 到底该不该使用存储过程 MySQL查询性能优化一则

    到底该不该使用存储过程   看到<阿里巴巴java编码规范>有这样一条 关于这条规范,我说说我个人的看法 用不用存储过程要视所使用的数据库和业务场景而定的,不能因为阿里巴巴的技术牛逼,就视 ...

  6. MySQL 数据库性能优化之索引优化

    接着上一篇 MySQL 数据库性能优化之表结构,这是 MySQL数据库性能优化专题 系列的第三篇文章:MySQL 数据库性能优化之索引优化 大家都知道索引对于数据访问的性能有非常关键的作用,都知道索引 ...

  7. SQL Server查询性能优化——覆盖索引(二)

    在SQL Server 查询性能优化——覆盖索引(一)中讲了覆盖索引的一些理论. 本文将具体讲一下使用不同索引对查询性能的影响. 下面通过实例,来查看不同的索引结构,如聚集索引.非聚集索引.组合索引等 ...

  8. SQL Server 查询性能优化——覆盖索引

    覆盖索引又可以称为索引覆盖. 解释一: 就是select的数据列只用从索引中就能够取得,不必从数据表中读取,换句话说查询列要被所使用的索引覆盖. 解释二: 索引是高效找到行的一个方法,当能通过检索索引 ...

  9. MySQL优化技巧之五(mysql查询性能优化)

    对于高性能数据库操作,只靠设计最优的库表结构.建立最好的索引是不够的,还需要合理的设计查询.如果查询写得很糟糕,即使库表结构再合理.索引再合适,也无法实现高性能.查询优化.索引优化.库表结构优化需要齐 ...

随机推荐

  1. django框架5

    内容概要 模板语法之过滤器(类似于内置函数) 模板语法之标签(类似于流程控制) 自定义过滤器.标签.inclusion_tag 模板的导入 模板的继承 注释语法补充 前期数据准备(测试环境搭建) al ...

  2. 1.Shell编程循环语句(if 、while、 until)

    循环语句 for循环语句 读取不同的变量值,用来逐个执行同一组命令 格式: for 变量名 in 取值列表 do 命令序列 done 示例:批量创建用户并设置密码 [root@localhost da ...

  3. SAP 实例 12 List Box with Value List from PBO Module

    REPORT demo_dynpro_dropdown_listbox. DATA: name TYPE vrm_id, list TYPE vrm_values, value LIKE LINE O ...

  4. NC16692 [NOIP2001]求先序排列

    NC16692 [NOIP2001]求先序排列 题目 题目描述 给出一棵二叉树的中序与后序排列.求出它的先序排列.(约定树结点用不同的大写字母表示,长度 ≤ 8). 输入描述 2行,均为大写字母组成的 ...

  5. 注册器机制Registry

    在众多深度学习开源库的代码中经常出现Registry代码块,例如OpenMMlab,facebookresearch和BasicSR中都使用了注册器机制.这块的代码经常会让新使用这些库的初学者感到一头 ...

  6. 如何用Fiddler对APP进行网络测试

    什么是Fiddler Fiddler是一个http协议调试代理工具,它能够记录并检查所有你的电脑和互联网之间的http通讯,设置断点,查看所有的"进出"Fiddler的数据(指co ...

  7. Conversation Modeling on Reddit Using a Graph-Structured LSTM

    publish: Transactions of the Association for Computational Linguistics,2016 tasks:  predicting popul ...

  8. mvc 捕获404和500 等

    之前一直以为HandleErrorAttribute 可以捕获到后面自己尝试了不行,又自己想自定义页面,发现不行,然后设置了<customErrors/>节点 又不符合SEO 返回stat ...

  9. 使用Three.js实现炫酷的赛博朋克风格3D数字地球大屏 🌐

    声明:本文涉及图文和模型素材仅用于个人学习.研究和欣赏,请勿二次修改.非法传播.转载.出版.商用.及进行其他获利行为. 背景 近期工作有涉及到数字大屏的需求,于是利用业余时间,结合 Three.js ...

  10. 2022-7-11第五组 pan小堂 js基础

    ##为何学习 JavaScript? ###JavaScript 是 web 开发者必学的三种语言之一: HTML 定义网页的内容 CSS 规定网页的布局 JavaScript 对网页行为进行编程 在 ...