索引条件下推(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. undefined reference to `BN_new'

    出现如下错误 undefined reference to `BN_CTX_new' undefined reference to `BN_new' undefined reference to `B ...

  2. maven的配置及基本操作

    ---恢复内容开始--- 1.官网下载maven 官方网址:http://maven.aparche.org 2.将maven解压到硬盘(最好没有中文路径)下 3.配置maven环境变量  4.配置m ...

  3. [linux] 进程五状态模型

    运行态:该进程正在执行:就绪态:进程做好了准备,只要有机会就开始执行:阻塞态:进程在某些事件发生前不能执行,如I/O 操作完成:新建态:刚刚创建的进程,操作系统还没有把它加入到可执行进程组中.通常是进 ...

  4. 常用的linux命令大全

    之前做过两年的运维,用过很多命令,深切体会到某些linux命令熟练掌握后对效率提升有多大.举个简单的例子,在做了研发后经常会有跑一些数据,对于结果数据的处理,我们的产品同学一般都习惯于用excel做统 ...

  5. ES6的相关语法

    1.ES6的兼容性 常用的是babel(也叫做browser.js); 用法: 直接在script中引用,把相应的script里面的type设置为text/babel 2.箭头函数 注意:1.如果只有 ...

  6. py2,py3区别 ,基础网络常识,多线程,

    1.编译型:把代码编译成机器码,计算机找虚拟机执行代码,机器码交给计算技巧去运行 :C语言,java c# 解释型:边解释边执行 5.只有列表才能reverse 字符串需要索引[::-1] 6.py2 ...

  7. JS高阶---闭包面试题

    [面试题1] 答案:The Window 分析: 本案例里,不存在闭包. 条件: .函数嵌套(满足) .内部函数调用外部函数变量(没有) 综上所述,该例中不存在闭包 [面试题2] 答案:My Obje ...

  8. JS中key-value存取

    获取Key 在代码中,遇到需要单独提取对象的key值时可使用 Object.keys(object) object是你需要操作的对象Object.keys()会返回一个存储对象中所有key值的数组获取 ...

  9. 第 33课 C++中的字符串(下)

    字符串与数字转换-标准库中提供了相关的类对字符串和数字进行转换-字符串流类(sstream)用于string的转换.<sstream>-相关头文件.istringstream-字符串输入流 ...

  10. 201871010108-高文利《面向对象程序设计(java)》第十周学习总结

    项目 内容 这个作业属于哪个课程 <任课教师博客主页链接> https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 <作业链接地址> ht ...