索引条件下推(ICP)是对MySQL使用索引从表中检索行的情况的优化。如果没有ICP,存储引擎会遍历索引以查找基表中的行,并将它们返回给MySQL服务器,该服务器会评估WHERE行的条件。启用ICP后,如果WHERE只使用索引中的列来评估部分 条件,MySQL服务器会推送这部分内容。WHERE条件下到存储引擎。然后,存储引擎通过使用索引条目来评估推送的索引条件,并且仅当满足该条件时才从表中读取行。ICP可以减少存储引擎必须访问基表的次数以及MySQL服务器必须访问存储引擎的次数。

指数条件下推优化的适用性受以下条件限制:

  • ICP用于 range, ref, eq_ref,和 ref_or_null访问方法时,有必要访问完整的表行。

  • ICP可用于表InnoDB 和MyISAM表,包括分区InnoDB和 MyISAM表。

  • 对于InnoDB表,ICP仅用于二级索引。ICP的目标是减少全行读取的数量,从而减少I / O操作。对于 InnoDB聚簇索引,已将完整记录读入InnoDB 缓冲区。在这种情况下使用ICP不会降低I / O.

  • 在虚拟生成列上创建的二级索引不支持ICP。InnoDB 支持虚拟生成列上的二级索引。

  • 引用子查询的条件无法下推。

  • 引用存储函数的条件无法下推。存储引擎无法调用存储的函数。

  • 触发条件无法下推。(有关触发条件的信息,请参见 第8.2.2.4节“使用EXISTS策略优化子查询”。)

要了解此优化的工作原理,请首先考虑在不使用索引条件下推时索引扫描的进度:

获取下一行,首先读取索引元组,然后使用索引元组找到并读取整个表行。

测试WHERE适用于此表的条件部分。根据测试结果接受或拒绝该行。

使用索引条件下推,扫描会像这样进行:

获取下一行的索引元组(但不是完整的表行)。

测试WHERE适用于此表的条件部分,并且只能使用索引列进行检查。如果不满足条件,则继续下一行的索引元组。

如果满足条件,请使用索引元组来查找并读取整个表行。

测试WHERE 适用于此表的条件的剩余部分。根据测试结果接受或拒绝该行。

EXPLAIN使用“索引条件下推”时,输出显示 Using index condition在 Extra列中。它没有显示,Using index 因为当必须读取完整的表行时,这不适用。

假设一个表包含有关人员及其地址的信息,并且该表的索引定义为 INDEX (zipcode, lastname, firstname)。如果我们知道一个人的zipcode价值但不确定姓氏,我们可以这样搜索:

SELECT * FROM people
WHERE zipcode='95054'
AND lastname LIKE '%etrunia%'
AND address LIKE '%Main Street%';

MySQL可以使用索引来扫描人 zipcode='95054'。第二部分(lastname LIKE '%etrunia%')不能用于限制必须扫描的行数,因此,如果没有Index Condition Pushdown,此查询必须为所有拥有的人检索完整的表行 zipcode='95054'。

使用索引条件下推,MySQL lastname LIKE '%etrunia%'在读取整个表行之前检查该 部分。这样可以避免读取与索引元组相对应的完整行,这些索引元组与zipcode条件匹配 但不符合 lastname条件。

默认情况下启用索引条件下推。可以optimizer_switch通过设置index_condition_pushdown标志来控制 系统变量 :

SET optimizer_switch = 'index_condition_pushdown=off';
SET optimizer_switch = 'index_condition_pushdown=on';

总结

1.对于 where constant + like查询可以尝试使用联合索引

// name和stu_id有联合索引
explain select * from course where name = 'ww' and stu_id like '%4%';

2.对于 where constant + order by index column可以尝试使用联合索引;

// name和stu_id有联合索引
explain select * from course where name = 'ww' order by stu_id;

以上另种情况都会使用Using index condition。第一种是过滤like的模糊匹配,第二种是进行联合索引的排序。

索引下推经常使用的场景:

  • 对于二级索引
  • select的列不使用覆盖索引
  • 多条件查询(where中多条件,where + order by) + 联合索引
参考

Index Condition Pushdown Optimization

Mysql系列(十二)—— 索引下推优化的更多相关文章

  1. 打开order by的大门,一探究竟《死磕MySQL系列 十二》

    在日常开发工作中,你一定会经常遇到要根据指定字段进行排序的需求. 这时,你的SQL语句类似这样. select id,phone,code from evt_sms where phone like  ...

  2. MySQL系列(十二)--如何设计一个关系型数据库(基本思路)

    设计一个关系型数据库,也就是设计RDBMS(Relational Database Management System),这个问题考验的是对RDBMS各个模块的划分, 以及对数据库结构的了解.只要讲述 ...

  3. mysql系列十二、mysql常用hint

    对于经常使用oracle的朋友可能知道,oracle的hint功能种类很多,对于优化sql语句提供了很多方法.同样,在mysql里,也有类似的hint功能.下面介绍一些常用的. 强制索引 FORCE ...

  4. 闯祸了,生成环境执行了DDL操作《死磕MySQL系列 十四》

    由于业务随着时间不停的改变,起初的表结构设计已经满足不了如今的需求,这时你是不是想那就加字段呗!加字段也是个艺术活,接下来由本文的主人咔咔给你吹. 试想一下这个场景 事务A在执行一个非常大的查询 事务 ...

  5. 聊聊MySQL的加锁规则《死磕MySQL系列 十五》

    大家好,我是咔咔 不期速成,日拱一卒 本期来聊聊MySQL的加锁规则,知道这些规则后可以判断SQL语句的加锁范围,同时也可以写出更好的SQL语句,防止幻读问题的产生,在能力范围内最大程度的提升MySQ ...

  6. 为什么不让用join?《死磕MySQL系列 十六》

    大家好,我是咔咔 不期速成,日拱一卒 在平时开发工作中join的使用频率是非常高的,很多SQL优化博文也让把子查询改为join从而提升性能,但部分公司的DBA又不让用,那么使用join到底有什么问题呢 ...

  7. Mysql优化(出自官方文档) - 第十二篇(优化锁操作篇)

    Mysql优化(出自官方文档) - 第十二篇(优化锁操作篇) 目录 Mysql优化(出自官方文档) - 第十二篇(优化锁操作篇) 1 Internal Locking Methods Row-Leve ...

  8. 为什么不建议给MySQL设置Null值?《死磕MySQL系列 十八》

    大家好,我是咔咔 不期速成,日拱一卒 之前ElasticSearch系列文章中提到了如何处理空值,若为Null则会直接报错,因为在ElasticSearch中当字段值为null时.空数组.null值数 ...

  9. MySQL 系列(二) 你不知道的数据库操作

    第一篇:MySQL 系列(一) 生产标准线上环境安装配置案例及棘手问题解决 第二篇:MySQL 系列(二) 你不知道的数据库操作 本章内容: 查看\创建\使用\删除 数据库 用户管理及授权实战 局域网 ...

  10. MySQL系列(二)---MySQL事务

    MySql 事务 目录 MySQL系列(一):基础知识大总结 MySQL系列(二):MySQL事务 什么是事务(transaction) 保证成批操作要么完全执行,要么完全不执行,维护数据的完整性.也 ...

随机推荐

  1. Qt发送邮件

    首先下载支持库 https://download.csdn.net/download/zhangxuechao_/10598108 #ifndef MAIL_H #define MAIL_H #inc ...

  2. 针对JCC指令练习的堆栈图

    堆栈图,主要目的就是练习一下JCC指令的熟练度,供参考 版权声明:本文为博主原创文章,转载请附上原文出处链接和本声明.2019-09-10,23:41:41.作者By-----溺心与沉浮----博客园 ...

  3. du查看某个文件或目录占用磁盘空间的大小

    一.du的功能:`du` reports the amount of disk space used by the specified files and for each subdirectory  ...

  4. elasticsearch 单节点出现unassigned_shards

    查看单节点Elasticsearch健康状态 使用head插件查看集群状态 从上面截图可以看出存在5个unassigned的分片,新建索引blog5的时候,分片数为5,副本数为1,新建之后集群状态成为 ...

  5. Django 使用 cookie 实现简单的用户管理

    Cookie: 1.保存在用户浏览器 2.可以主动清除 3.可以被伪造 4.跨域名 Cookie 不共享 创建一个项目:user_manager 和应用: app01 创建数据库,添加 models. ...

  6. seafile部署安装

    安装epel源 yum install epel-release -y 安装docker yum install -y docker service docker start systemctl en ...

  7. Ubuntu 18.04安装 CUDA 10.1 、cuDNN 7.6.5、PyTorch1.3

    转载请注明出处  BooTurbo https://www.cnblogs.com/booturbo/p/11834661.html 安装平台及环境 CPU:i9-9900k桌面级 GPU:RTX 2 ...

  8. 快速、优雅的前端IDE之H-builder-X

    为什么介绍的是HBuidler-X而不是Hbuilder   HX是全新的一个软件,它抛弃了eclipse架构,使用C++为基础架构.HX目前还不能完全替代HBuilder.但在markdown记事的 ...

  9. USB摄像头驱动框架分析

    usb摄像头驱动程序,里面涉及硬件的操作.比如说,想设置亮度的时候,需要把亮度的参数发给硬件.去得到真正视频数据的时候,需要访问硬件得到数据.usb摄像头驱动程序框架与虚拟摄像头驱动程序的框架是一样的 ...

  10. Linux查看网卡传输速率总结

    1.使用ethtool命令 ethtool ens192   使用ethtool命令后面直接接网卡名称可以查看到部分信息,包括网卡协商速率等等.   还有一种如果服务器内有很多块网卡,我们想查看具体网 ...