MySQL篇—执行计划之覆盖索引Using index和条件过滤Using where介绍(第三篇,总共三篇)

news2024/11/17 15:28:56

☘️博主介绍☘️

✨又是一天没白过,我是奈斯,DBA一名✨

✌️擅长Oracle、MySQL、SQLserver、Linux,也在积极的扩展IT方向的其他知识面✌️

❣️❣️❣️大佬们都喜欢静静的看文章,并且也会默默的点赞收藏加关注❣️❣️❣️

    SQL语句的执行计划复杂多变,每一次的查询都可能带来截然不同的执行策略。为了真正掌握其内在的工作机制,我们必须深入生产环境,通过反复的实践与观察来积累经验。今天将聚焦于explain Extra输出列中的两个关键要素:“Using index”和“Using where”,带大家一起看一下Using index和Using where对查询计划的影响,当然今天的介绍只是众多Extra输出列中其中的两个。希望通过这篇文章,能够帮助大家更好地理解SQL查询的执行过程,以及如何更有效地优化查询性能。

    今天作为统计信息和执行计划的最后一篇,让我们回顾一下前两篇的介绍内容:

第一篇:持久化和非持久化统计信息介绍

第二篇:执行计划介绍

第三篇:执行计划之覆盖索引Using index和条件过滤Using where详细介绍(当前篇)



            

目录

一、Using index:使用覆盖索引。属于积极现象,一般不需要过多再去干预。

案例:不使用覆盖索引的情况和使用覆盖索引的情况

不使用覆盖索引的情况:

 使用覆盖索引的情况:

二、Using where:条件中的字段没有使用索引,或者部分字段没有使用索引。属于消极现象,进行分析干预。

案例:使用到Using where的情况和不使用到Using where的情况

使用到Using where的情况:

不使用到Using where的情况:


          

一、Using index:使用覆盖索引。属于积极现象,一般不需要过多再去干预。

注意:是使用了覆盖索引,和使用索引不是一个概念,有没有使用索引通过key输出列确定。

          

官方文档介绍:MySQL :: MySQL 8.0 Reference Manual :: 10.8.2 EXPLAIN Output Format

    使用索引(JSON属性:Using_index)

    只使用索引树中的信息从表中检索列信息,而不必进行额外的查找来读取实际行。当查询仅使用作为单个索引一部分的列时,可以使用此策略。

    对于具有用户定义的聚集索引的InnoDB表,即使Extra列中没有Using索引,也可以使用该索引。如果类型为索引,键为PRIMARY,则会出现这种情况。

    显示了EXPLAIN FORMAT=TRADINAL和EXPLAIN ORMAT=JSON所使用的任何覆盖索引的信息。从MySQL 8.0.27开始,它也显示为EXPLAIN FORMAT=TREE。

           

覆盖索引(Covering Index):

    如果一个索引包含了查询所需的所有字段,则称该索引为覆盖索引。当MySQL查询使用这个索引时,它可以直接从索引中获取所有需要的数据,而无需再回表(即返回原表)查找。

    在查询执行计划中,当出现“Using index”时,意味着MySQL已经使用了覆盖索引(Covering Index)来检索数据。这是一个优化提示,表明查询可以仅通过索引来满足,而无需访问实际的数据表。

    出现覆盖索引的好处:1、减少I/O操作:因为MySQL可以仅通过索引获取数据,所以它不需要读取整个表的数据,这通常意味着更少的磁盘I/O操作。

                                        2、提高查询速度:由于减少了I/O操作和可能的表查找,查询通常会更快。

                                        3、减少内存使用:由于不需要从表中读取额外的数据,所以内存使用可能会更低。

    需要注意的是,虽然“Using index”是一个优化提示,但在某些情况下,它可能不是最优的。例如,如果查询中的某些条件不能有效地使用索引,或者索引本身非常大,那么全表扫描可能更快。

             

回表(Back to Table):

    "回表"是指当查询语句需要获取的数据不仅仅在索引中,还需要回到主表中进行二次查询获取的过程。

1、回表的影响:回表操作会增加额外的I/O操作和访问时间,影响查询的性能。因为回表需要额外的查找步骤,所以在高并发的情况下,回表操作会导致数据库的负载增加,可能会成为性能瓶颈。

2、如何避免回表:为了避免回表操作,可以使用覆盖索引(Covering Index)的方式。覆盖索引是指创建一个包含了查询所需的所有列的索引,这样就可以直接从索引中获取所需的数据,而无需回到表中查找。使用覆盖索引可以减少I/O操作和提高查询性能。

3、如何优化回表:如果无法避免回表操作,可以通过以下方法进行优化:

                   一、优化查询语句:尽量减少回表操作的次数,可以通过合理的查询条件、索引设计和查询优化等方式来减少回表操作。

                   二、调整表结构:如果回表操作非常频繁,可以考虑调整表结构,将需要查询的列放在索引中,或者使用聚簇索引来减少回表操作。

                   三、使用缓存:如果查询的数据具有一定的重复性,可以考虑使用缓存来减少回表操作。

         

覆盖索引触发的条件

1、没有where条件,select查询的返回列包含在索引列中:这意味着查询的结果可以直接从索引中获取,而无需访问实际的数据表。

2、有where条件where和select都要包含索引列或复合索引:这有助于数据库系统更有效地利用索引进行查找和过滤。

3、查询结果的总字段长度可以接受:如果查询结果的总字段长度过大,可能不适合使用覆盖索引,因为这可能会增加系统的开销。

    当满足上述条件时,数据库系统可能会选择使用覆盖索引来执行查询,从而提高查询的效率。不过,请注意,索引的使用和优化是一个复杂的过程,具体是否使用覆盖索引还取决于数据库管理系统的具体实现和查询的具体情况。

          

案例:不使用覆盖索引的情况和使用覆盖索引的情况

mysql> show index from tb_200w;   ---表现在无索引

mysql> create index idx_tb_200w_ina on tb_200w(id,name,age);    ---创建索引

          

不使用覆盖索引的情况:

1)没有where条件,select查询的返回列没有在索引列中:

mysql> explain select * from tb_200w;
mysql> explain select sex from tb_200w;
mysql> explain select age,sex from tb_200w;    ---select中包含了索引列和没有索引的列,这种情况肯定是不会使用到覆盖索引的,因为查询语句需要获取的数据不仅仅在索引中,还需要回到主表中进行二次查询获取的过程。

            

2)有where条件where或select没有包含索引列或复合索引:

mysql> explain select * from tb_200w where id=1;
mysql> explain select sex from tb_200w where id=1;
mysql> explain select age,sex from tb_200w where id=1;    ---where包含了索引列,但是select中包含了索引列和没有索引的列,这种情况肯定是不会使用到覆盖索引的,因为查询语句需要获取的数据不仅仅在索引中,还需要回到主表中进行二次查询获取的过程。

    

          

 使用覆盖索引的情况:

1)没有where条件,select查询的返回列包含在索引列中: 

mysql> explain select id from tb_200w;
mysql> explain select name from tb_200w;
mysql> explain select age from tb_200w;
mysql> explain select name,age from tb_200w;  
mysql> explain select age,id from tb_200w;                 ---都会使用到覆盖索引,因为select查询的返回列包含在索引列中了

         

2)有where条件where和select都要包含索引列或复合索引:

mysql> explain select id from tb_200w where id=1;
mysql> explain select name from tb_200w where id=1;
mysql> explain select age from tb_200w where id=1;
mysql> explain select name,age from tb_200w where id=1;
mysql> explain select age,id from tb_200w where id=1;      ---都会使用到覆盖索引,因为where和select都包含索引列或复合索引了

         

    

二、Using where:条件中的字段没有使用索引,或者部分字段没有使用索引。属于消极现象,进行分析干预。

         

官方文档介绍:MySQL :: MySQL 8.0 Reference Manual :: 10.8.2 EXPLAIN Output Format

    使用where(JSON属性:attached_condition)

    WHERE子句用于限制哪些行与下一个表匹配或发送到客户端。除非您特别打算从表中提取或检查所有行,否则如果Extra值不是Using where,并且表联接类型是all或index,则查询中可能会出现错误。

            

 Using where介绍:

    Using where表示查询在检索到行之后,需要使用WHERE子句中的条件对这些行进行过滤。这并不一定意味着查询没有使用索引,而是意味着即使有索引被使用,索引本身并不能完全满足WHERE子句中的所有条件,因此MySQL需要读取实际的行数据,并在服务器层面对这些行进行额外的过滤。

            

Using where触发的条件:

1、复合索引与部分条件匹配:如果你有一个复合索引(例如 (a, b, c)),但你的WHERE子句只涉及索引的前两个字段(例如 WHERE a = 1 AND b = 2),那么MySQL可以使用这个复合索引来快速找到匹配的行。但是,如果WHERE子句还包含第三个字段的条件(例如 c > 3),则即使索引被使用,Using where 也会出现在执行计划中,因为需要对找到的行进行额外的过滤。

2、没有合适的索引:如果查询的WHERE子句条件没有对应的索引,或者索引的选择性不高(即索引中的不同值不多),MySQL可能会选择全表扫描而不是使用索引。在这种情况下,Using where 会出现在执行计划中,因为所有检索到的行都需要进行过滤。

           

避免Using where的触发:

    Using where 的出现并不一定意味着查询性能不佳。实际上,在很多情况下,即使需要额外的过滤,使用索引仍然比全表扫描更快。然而,如果发现Using where经常出现并且查询性能不佳,需要考虑:

1、添加或优化索引:确保你的查询条件有合适的索引支持。

2、调整查询:尝试重写查询或分解复杂查询为多个简单查询,以便更好地利用索引。

3、分析数据和索引统计信息:使用ANALYZE TABLE命令更新表的统计信息,以便MySQL优化器能够做出更好的决策。

               

案例:使用到Using where的情况和不使用到Using where的情况

mysql> show index from tb_200w;   ---表现在无索引

mysql> create index idx_tb_200w_id on tb_200w(id);                 ---创建单列索引
mysql> create index idx_tb_200w_ina on tb_200w(name,age,cardid);   ---创建复合索引

        

使用到Using where的情况:

mysql> explain select * from tb_200w where tel=13604981449;      ---直接查询普通列,而不引用索引列
mysql> explain select * from tb_200w where age=38;               ---查询的列在复合索引中,但是并没有引用前置列(name列),所以不会使用到索引
mysql> explain select * from tb_200w where cardid=1000110123;     ---查询的列在复合索引中,但是并没有引用前置列(name列),所以不会使用到索引

               

不使用到Using where的情况:

mysql> explain select * from tb_200w where id=1000;       ---使用单列索引
mysql> explain select * from tb_200w where name='n1000';     ---使用复合索引,引用了前置列(name列)
mysql> explain select * from tb_200w where name='n1000' and age=38 and cardid='1000110123';
---使用复合索引,引用了前置列(name列)

    关于统计信息和执行计划的内容全部就到这里,执行计划所涉及的内容太过广泛,我所介绍的内容也只是冰山一角,以后就靠大家自己去学习和实践。当然我也会继续在CSDN上分享关于执行计划的内容。

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

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

相关文章

python实现手机号归属地查询

手机上突然收到了某银行的短信提示,看了一下手机的位数,正好是11位。我一想,这不就是标准的手机号码吗?于是一个想法涌上心头——用python的库实现查询手机号码归属地查询自由。 那实现的效果如下: 注:电…

yolov7添加spd-conv注意力机制

一、spd-conv是什么? SPD-Conv(Symmetric Positive Definite Convolution)是一种新颖的卷积操作,它主要应用于处理对称正定矩阵(SPD)数据。在传统的卷积神经网络(CNN)中,…

【java数据结构】模拟二叉树的链式结构之孩子表示法,掌握背后的实现逻辑

📢编程环境:idea 📢树结构,以及叶子,结点,度等一些名词是什么意思,本篇不再赘述。 【java数据结构】模拟二叉树的链式结构之孩子表示法,掌握背后的实现逻辑 1. 认识二叉树1.1 二叉树…

桂院校园导航 | 云上高校导航 云开发项目 二次开发教程 2.0

Gitee代码仓库:桂院校园导航小程序 GitHub代码仓库:GLU-Campus-Guide 演示视频 【校园导航小程序】2.0版本 静态/云开发项目 演示 云开发项目 2.0版本 升级日志 序号 板块 详情 1 首页 重做了首页,界面更加高效和美观 2 校园页 新增…

Python判断结构20个实例

基本理论基础 Python中的选择判断结构是一种编程中常用的控制结构,它用于根据条件的真假决定程序的执行路径。选择判断结构有多种类型,包括if语句、if-else语句、if-elif-else语句以及嵌套的选择结构。 首先,我们来介绍最常见的if语句。if语…

浅谈WPF之Binding数据校验和类型转换

在WPF开发中,Binding实现了数据在Source和Target之间的传递和流通,就像现实生活中的一条条道路,建立起了城镇与城镇之间的衔接,而数据校验和类型转换,就像高速公路之间的收费站和安检站。那在WPF开发中,如何…

引入本地图片报错:require is not defined

文章目录 问题分析1. 原始写法2. 最初的解决方案3. 尝试使用 require 引入4. 封装方法进行解析引入图片 问题 Vue3 Vite 使用本地图片报错:require is not defined 分析 1. 原始写法 刚开始我是这样写的,数据是这样定义的,但是数据没出…

Vue.js+SpringBoot开发高校实验室管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容2.1 实验室类型模块2.2 实验室模块2.3 实验管理模块2.4 实验设备模块2.5 实验订单模块 三、系统设计3.1 用例设计3.2 数据库设计 四、系统展示五、样例代码5.1 查询实验室设备5.2 实验放号5.3 实验预定 六、免责说明 一、摘…

2024年R2移动式压力容器充装证考试题库及R2移动式压力容器充装试题解析

题库来源:安全生产模拟考试一点通公众号小程序 2024年R2移动式压力容器充装证考试题库及R2移动式压力容器充装试题解析是安全生产模拟考试一点通结合(安监局)特种作业人员操作证考试大纲和(质检局)特种设备作业人员上…

快速幂(求解原理+例题)

目录 反复平方法(快速幂): 代码: 例题:快速幂求逆元 作用: 快速求出 的结果。 时间复杂度: O(logk) 如果使用一般做法,从1循环到k,时间复杂度是O(k) 反复平方法&am…

倒计时35天

小红的子序列权值和 (nowcoder.com) #include<bits/stdc.h> using namespace std; #define int long long const int N2e56; const int inf0x3f3f3f3f; const double piacos(-1.0); const int mod1e97; int c[1100][1100]; int a[1100],b[5]; void solve() {int n;cin>…

照片变年轻怎么操作?收好这几个方法

照片变年轻怎么操作&#xff1f;在这个数字时代&#xff0c;我们手中的智能手机和相机成为了记录生活的重要工具。然而&#xff0c;随着时间的推移&#xff0c;照片中的人物往往会因为岁月的痕迹而显得苍老。那么&#xff0c;有没有一种方法可以让这些珍贵的回忆重新焕发青春呢…

[DevOps云实践] 跨AWS账户及Region调用Lambda

[DevOps云实践] 跨AWS账户及Region调用Lambda 本文將幫大家理清一下幾個問題: 如何跨不同AWS賬戶,不同Region來調用Lambda? 不同Lambda之間如何互相調用?有時我們希望我們的Lambda脚本能夠運行在多個AWS賬戶中的不同Region下,但是,我們還不希望每個下面都去建立一個運行…

从0开始学习NEON(1)

1、前言 在上个博客中对NEON有了基础的了解&#xff0c;本文将针对一个图像下采样的例子对NEON进行学习。 学习链接:CPU优化技术 - NEON 开发进阶 上文链接:https://blog.csdn.net/weixin_42108183/article/details/136412104 2、第一个例子 现在有一张图片&#xff0c;需…

【CSP试题回顾】201403-2-窗口

CSP-201403-2-窗口 解题思路 窗口存储结构&#xff1a;首先&#xff0c;使用一个结构体MyWindow来存储每个窗口的信息&#xff0c;包括窗口的序号&#xff08;index&#xff09;和矩形区域的四个顶点坐标&#xff08;x1, y1, x2, y2&#xff09;。所有窗口的信息存储在一个向量…

17 easy 290. 单词规律

//给定一种规律 pattern 和一个字符串 s &#xff0c;判断 s 是否遵循相同的规律。 // // 这里的 遵循 指完全匹配&#xff0c;例如&#xff0c; pattern 里的每个字母和字符串 s 中的每个非空单词之间存在着双向连接的对应规律。 // // // // 示例1: // // //输入: patte…

一篇文章教会你如何在IOS真机上完美运行React Native

一篇文章教会你如何在IOS真机上完美运行React Native 项目初始化项目配置可能遇到的问题没有账号也没有Team设备上没有打开开发者模式&#xff0c;也没有信任开发者证书 无线调试 项目初始化 在终端使用**npx react-native init ProjectName**初始化React Native项目。 进入项…

selenuim【1】$x(‘xpath’)、WebDriverWait()、try/assert

文章目录 1、执行driver webdriver.Chrome()后很久才打开浏览器2、浏览器多元素定位 $x(‘xpath语法’)3、打开浏览器driver.get("网址")执行了很久才开始定位元素&#xff1a;等待&#xff08;1&#xff09;driver.set_page_load_timeout(t)&#xff08;2&#xff…

Live Home 3D Pro:您的私人家居设计师,让家更有温度

Live Home 3D Pro是一款功能强大的家居设计软件&#xff0c;它凭借直观的用户界面和丰富的设计工具&#xff0c;为用户提供了一个全新的家居设计体验。无论您是专业设计师还是普通用户&#xff0c;Live Home 3D Pro都能帮助您轻松实现家居设计的梦想。 Live Home 3D Pro mac版…

枚举与尺取法(蓝桥杯 c++ 模板 题目 代码 注解)

目录 组合型枚举&#xff08;排列组合模板&#xff08;&#xff09;&#xff09;: 排列型枚举&#xff08;全排列&#xff09;模板&#xff1a; 题目一&#xff08;公平抽签 排列组合&#xff09;&#xff1a; ​编辑 代码&#xff1a; 题目二&#xff08;座次问题 全排…