【MySQL精通之路】优化(1)-查询优化(6)-索引条件下推

1.介绍

        Index Condition Pushdown(ICP)是针对MySQL使用索引从表中检索行的情况进行的优化。

        在没有ICP的情况下,存储引擎遍历索引以定位基表中的行,并将它们返回给MySQL服务器,MySQL服务器会评估这些行的WHERE条件。

        启用ICP后,如果仅使用索引中的列就可以计算WHERE条件的一部分,MySQL服务器会将WHERE条件的这一部分推送到存储引擎。然后,存储引擎通过使用索引条目来评估推送的索引条件,只有当满足这一条件时,才从表中读取行。ICP可以减少存储引擎必须访问基表的次数和MySQL服务器必须访问存储引擎的次数。

2.触发限制

指数条件下推优化的适用性受以下条件的约束:

当需要访问完整的表行时,ICP用于rangerefeq_refref_or_null访问方法。

ICP可用于InnoDBMyISAM表,包括分区的InnoDBMyISAM表

对于InnoDB表,ICP仅用于二级索引。ICP的目标是减少整行读取的次数,从而减少I/O操作。对于InnoDB聚集索引完整的记录已经读取到InnoDB缓冲区中。在这种情况下使用ICP不会减少I/O

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

引用子查询的条件不能向下推。

包含存储函数的查询条件无法下推。存储引擎无法调用存储的函数。

触发式的条件查询无法下推。

(有关触发条件的信息,请参阅“使用EXISTS策略优化子查询”。)

(MySQL 8.0.30及更高版本:)不能将条件查询下推到包含对系统变量的引用的派生表中

要了解此优化是如何工作的,请首先考虑在不使用“索引条件下推”时索引扫描是如何进行的:

1.获取下一行,首先读取索引元组,然后使用索引元组定位并读取整个表行。

2.WHERE条件中匹配此表的部分行。根据匹配结果接受或拒绝该行。

使用索引条件下推,扫描按如下方式进行:

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

2.WHERE条件中匹配此表的部分行,并且只能使用索引列进行检查。如果条件不满足,请转到下一行的索引元组。

3.如果满足条件,则使用索引元组来定位和读取整个表行。

4.匹配此表的WHERE条件的剩余部分。根据匹配结果接受或拒绝该行。

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


3.示例

假设一个表包含有关人员及其地址的信息,

并且该表有一个定义为index(zipcode,lastname,firstname)的索引。如果我们知道一个人的邮政编码值,但不确定他的姓氏,我们可以这样搜索:

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

MySQL可以使用索引扫描zipcode='95054'的人

第二部分(lastname LIKE“%etrunia%”)不能用于缩小必须扫描的行数,因此如果没有索引条件下推,此查询必须为所有邮政编码为“95054”的人检索完整的表。

使用Index Condition Pushdown,MySQL在读取完整的表行之前检查姓氏LIKE“%etrunia%”部分。这样可以避免读取与zipcode条件匹配但与lastname条件不匹配的索引元组对应的完整行

默认情况下,“索引条件下推”处于启用状态

可以通过设置index_condition_pushdown标志,使用optimizer_switch系统变量进行控制:

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

博主PS:

这里官网的示例如果还不够清晰,我们回想一下,MySQL是有聚簇索引和二级索引(辅助索引)的,这里我们讨论Innodb引擎的情况,也就是说在index(zipcode,lastname,firstname)的索引的索引列上,二级索引也是一个B+树。它每个节点存放的就是索引列的值,当索引走到zipcode=95054这个索引下的时候,那么它的下一级子树肯定都是邮编为95054,姓lastname不确定,名firstname不确定的索引了。(因为联合索引的排序规则是先排序前面索引的key,再排序后面的。)

或者说此index(zipcode,lastname,firstname)联合索引所生成的二级索引B+树,已经按zipcode排序,再按lastname排序,再按fisrtname排序了。所以当根据最左匹配原则匹配到了95054索引后,再多进行一次判断(对第二列的匹配判断),因为此时,第二列索引的值和95054在一个节点下,或之下,我只需要判断当前这个联合索引的第二个索引字段值是否匹配where的第二个字段的模糊查。这样不需要再去聚簇索引查找数据行了、如果不下推,那么我需要把95054这个索引所匹配的二级索引的所以数据行回表查询,去聚簇索引查出所有的数据行,再与where条件第二个判断。我们知道二级索引的叶子节点数据行存放的是聚簇索引的主键。这时候他需要全量回表查询,回表次数可能会相当大,但是我如果直接通过联合索引上的索引的key来判断where条件查询的值是否符合这个key,就可以过滤掉很大一部分二级索引上的数据,只有那种实在无法定位的数据,再通过主键回表查询。比如第三个where条件是地址,这个联合索引根本就没有地址字段的联合索引。那么此时数据库手里已经有一堆被邮编和姓名过滤过的数据了,再用这些数据的主键。去聚簇索引判断地址数据。


如果你还不懂 那么举一个相亲的例子。聚簇索引里,人们的【个人信息数据】通过身份证号组成一颗B+树。B+树的叶子节点就是那个人的全部个人信息。

现在建立了一个由国家,年龄,身高,性别为联合索引的二级索引树。

这时候你的where条件是:国家=中国,年龄=18岁,性别=女,的一个where查询。

正常来说这个 国家,年龄,性别的where查询。只有国家年龄符合最左匹配,他可以使用到索引,但是性别用不了索引查询(不符合最左匹配),需要回表查询。

但是你现在手里已经查询到所有 “国家=中国 和 年龄18岁,身高不确定,性别不确定的”人了索引集合了。

因为没有回表去匹配身高,和性别的人,索引这里是不限。但是聪明的你已经想到。

本来就只需要查性别了,性别的数据在当前的联合索引里是有的,我只需要在联合索引里判断一下联合索引里的性别数据,看看哪些索引是女性索引,是不是就能把where条件里的过滤条件满足完了??

没有ICP之前,数据库会把在二级索引查找到所有满足国家=中国 和 年龄18岁的主键返回,并去聚簇索引查找性别为女的数据行。

这就是索引下推。如果二级索引的索引key可以用来对where条件进行过滤,不用再使用二级索引的叶子节点数据行主键去聚簇索引回表查询,那么就可以下推判断。这时候可以破坏最左匹配原则。

参见“可切换优化”。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/18051.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

开源VS闭源:谁将引领AI大模型的新时代?

一、引言 随着人工智能技术的飞速发展,AI大模型已成为推动这一浪潮的核心动力。在AI大模型的发展过程中,开源与闭源两种不同的发展路径一直备受关注。本文将深入探讨这两种路径的优劣势,分析它们对AI大模型发展的影响,并预测谁将…

ctfshow web入门 黑盒测试

web380 这里文章看的我好有感触 但是影响做题 扫描一下 访问flag.php啥也没有再访问page.php page.php?idflagweb381 扫出来page.php但是没啥用哇,查看源代码 这些文件挨个试发现啥也没,最后仔细对比发现其实都是layui,然后尝试着访问…

《架演》共创者第一次线上沟通会议总结

《架演》共创者第一次线上沟通——启动会 会议主题:《架演》共创启动会议会议时间:2024年5月28日,20:00 - 21:00会议地点:腾讯会议主持人:寒山参会人员: 夏军、mirror、刘哥、悟缺席人员:可心、…

Cocos Creator 安卓环境配置

系统:Win10,引擎版本:CocosCreator3.8.2, 时间:2024.05.23 安装 Java SDK(JDK)下载地址 注意:Java版本对应的Gradle: 详见表 Table 1. Java Compatibility 此处选择 Java 21 对应 Gradle 8.5 配置Java系统…

2024.05.22学习记录

1、面经复习: Vue组件通讯、vuex、js严格模式、options请求、vue3 Setup 语法糖、React hook 2、代码随想录刷题:动态规划 3、rosebush组件库 完成Alert和Alert测试 Menu组件初步开发

RocketMQ 主从复制原理深度解析

提到主从复制,我们可能立马会联想到 MySQL 的主从复制。 MySQL 主从复制是 MySQL 高可用机制之一,数据可以从数据库服务器主节点复制到一个或多个从节点。 这篇文章,我们聊聊 RocketMQ 的主从复制,希望你读完之后,能…

文献解读-群体基因组第一期|《对BMI的影响:探究BMI的基因型-环境效应》

关键词:应用遗传流行病学;群体测序;群体基因组;基因组变异检测; 文献简介 标题(英文):The Impact of ACEs on BMI: An Investigation of the Genotype-Environment Effects of BMI标…

智能家居3 - 实现烟雾报警模块

这一模块的思路和前面的语言控制模块很相似&#xff0c;差别只是调用TCP 去控制 废话少说&#xff0c;放码过来 增添/修改代码 smoke_interface.c #include <pthread.h> #include <wiringPi.h> #include <stdio.h>#include "smoke_interface.h" …

knex与sequelize 以及断点工具使用

knex 使用 SQL Query Builder for Javascript | Knex.js 首先下载 npm install knex 使用 const knex require(knex)({client: mysql,connection: {host: localhost, // 地址user: root, // 账号password: 123456, // 密码database: user // 数据库}});/*** kn…

React-组件基础使用

组件是什么 概念&#xff1a;一个组件就是用户界面的一部分&#xff0c;它可以有自己的逻辑和外观&#xff0c;组件之间可以互相嵌套&#xff0c;也可以复用多次 组件化开发可以让开发者像搭积木一样构建一个完整的庞大的应用 React组件 在React中&#xff0c;一个组件就是首…

云动态摘要 2024-05-24

给您带来云厂商的最新动态&#xff0c;最新产品资讯和最新优惠更新。 最新优惠与活动 [免费试用]大模型知识引擎体验招募 腾讯云 2024-05-21 大模型知识引擎产品全新上线&#xff0c;为回馈新老客户&#xff0c;50万token免费送&#xff0c;开通服务即领取&#xff01; 云服…

git教程(IDEA + 命令行)

首先假设你已经安装 git 且 已经初始化完成&#xff1a; // 初始化git config --global user.name "你的用户名" git config --global user.email "你的邮箱"在当前文件夹下创建一个仓库&#xff0c;且该文件夹下会有多个项目 首先在当前文件夹下新建git…

微信小程序毕业设计-校园综合服务系统项目开发实战(附源码+论文)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;微信小程序毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计…

JavaScript-对象

对象的概念 所有事物都可以是对象,对象可以是一种数据类型&#xff0c;或多种数据类型&#xff0c;也可以是一个函数或多个函数。 在一个程序里面&#xff0c;通常会用多个变量来描述一些实体的属性 对象是JavaScript的一种数据类型 例如描述一个学生&#xff0c;它的属性应该是…

VSCode开发Python-Django入门

一、安装配置Python环境及配置Python环境变量 1、python安装包安装后&#xff0c;需要注意pip.exe和pip3.exe的安装&#xff1b; 2、环境变量需要配置两个目录&#xff1b; 3、验证python是否安装成功 通过cmd命令执行&#xff1a;python --version 查看python版本&#xff…

理解JavaScript的内存管理详解

JavaScript的内存管理是指如何分配、使用和释放内存的过程。在JavaScript中&#xff0c;内存管理是由JavaScript引擎自动处理的&#xff0c;开发者不需要手动操作内存。 JavaScript使用垃圾回收器来管理内存。垃圾回收器的主要任务是找出不再使用的内存&#xff0c;并将其释放…

【前端每日基础】day25——事件处理

事件处理 事件处理允许网页响应用户的交互&#xff0c;例如点击、键盘输入、鼠标移动等。 添加事件监听器 可以使用addEventListener来添加事件监听器&#xff1a; let button document.getElementById("myButton");// 添加点击事件监听器 button.addEventListene…

高中生是否需要上电子阅览室

高中生是否需要上电子阅览室&#xff0c;取决于学生的学习需求和个人喜好。以下是一些考虑因素&#xff1a; 1. 便利性&#xff1a;电子阅览室通常提供电脑设备和网络连接&#xff0c;方便学生在线获取学习资源。对于家中没有电脑或者网络不稳定的学生&#xff0c;上电子阅览室…

实战

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 实战一&#xff1a;模拟支付宝蚂蚁森林的能量产生过程 支付宝的蚂蚁森林通过日常的走步、生活缴费、线下支付、网络购票、共享单车等低碳、环保行为…

pyspark==windows单机搭建

下载安装JDK17,配置JAVA_HOME 下载安装hadoop-3.3.5并完整替换bin目录,配置HADOOP_HOME Index of /hadoop/common/hadoop-3.3.5 GitHub - cdarlint/winutils: winutils.exe hadoop.dll and hdfs.dll binaries for hadoop windows 下载spark配置SPARK_HOME 安装pyspark Demo …