当前位置: 首页 > news >正文

【MySQL从入门到精通】【高级篇】(二十五)EXPLAIN中ref、rows、filtered、Extra字段的剖析

您好,我是码农飞哥,感谢您阅读本文,欢迎一键三连哦
💪🏻 1. Python基础专栏,基础知识一网打尽,9.9元买不了吃亏,买不了上当。 Python从入门到精通
❤️ 2. Python爬虫专栏,系统性的学习爬虫的知识点。9.9元买不了吃亏,买不了上当 。python爬虫入门进阶
❤️ 3. Ceph实战,从原理到实战应有尽有。 Ceph实战
❤️ 4. Java高并发编程入门,打卡学习Java高并发。 Java高并发编程入门
😁 5. 社区逛一逛,周周有福利,周周有惊喜。码农飞哥社区,飞跃计划

文章目录

    • 1. 简介
    • 2. 测试的表和数据
    • 3. ref
    • 4. rows
    • 5. filtered
    • 6. Extra
      • 6.1. No tables used
      • 6.2. Using where
      • 6.3. Using index
      • 6.4. Using index condition
      • 6.5. Using join buffer (Block Nested Loop)
      • 6.6. Not exists
      • 6.7. Using union
      • 6.8. Using filesort
      • 6.9. Using temporary
      • 6.10 小结
    • 7. EXPLAIN 四种输出格式
      • 7.1. 传统格式
      • 7.2. JSON格式
    • 8. 总结

1. 简介

上一篇文章我们介绍了
【MySQL从入门到精通】【高级篇】(二十四)EXPLAIN中select_type,partition,type,key,key_len字段的剖析,重点介绍了EXPLAIN命令的select_type,partition,type,key,key_len 字段含义。这篇文章我将接着介绍剩余字段的含义。本文会介绍ref、rows、filtered、Extra这几个字段。比较重要的两个字段是rows、Extra

2. 测试的表和数据

在这里插入图片描述
详细的测试表创建以及插入测试数据,请参见:【MySQL从入门到精通】【高级篇】(二十三)EXPLAIN的概述与table,id字段的剖析,其中:Extra 字段非常重要

3. ref

ref:当使用索引列等值查询时,与索引列进行等值匹配的对象信息。比如只是一个常数或者某个列。
测试的SQL

EXPLAIN SELECT * FROM s1 WHERE common_field='A';

EXPLAIN SELECT * FROM s1 WHERE key1='a';

EXPLAIN SELECT * FROM s1 INNER JOIN s2 ON s1.id=s2.id;

EXPLAIN SELECT * FROM s1 INNER JOIN s2 ON s2.key1=UPPER(s1.key1);
  1. 使用非索引列
    在这里插入图片描述

  2. 使用索引列进行常数等值查询
    在这里插入图片描述

  3. 使用主键关联查询
    这里会列出数据库名.表名.字段名
    在这里插入图片描述

  4. 使用索引列 包含函数查询
    这里列出的则是表示使用到了函数
    在这里插入图片描述

4. rows

rows: 预估的需要读取的记录条数,值越小越好
测试的SQL语句

EXPLAIN SELECT * FROM s1 WHERE key1='z';
EXPLAIN SELECT * FROM s1 WHERE key1>'z';
  1. 可以通过索引精确查找
    这里key1='z' 可以直接通过索引精确查找,所以预估的rows为1。
    在这里插入图片描述
  2. 范围查找
    这里key1>'z' 可以不能通过索引精确查找,所以预估的rows大于1。这里的rows值为398。
    在这里插入图片描述

5. filtered

filtered 表示某个表经过搜索条件过滤后剩余记录条数的百分比,如果使用的是索引执行的单表扫描,那么计算时需要估计出满足除使用到对应索引的搜索条件外的其他搜索条件的记录有多少条。

  1. 单表查询的情况
EXPLAIN SELECT * FROM s1 WHERE key1>'z' AND common_field='a';

在这里插入图片描述
这里s1表预计扫描了398条记录,其中10%满足条件。
2. 连接查询的情况
对于单表查询来说,这个filtered列的值没什么意义,我们更关注在连接查询中驱动表对应的执行计划记录的filtered值,它决定了被驱动表要执行的次数(即:rows*filtered)

EXPLAIN SELECT * FROM s1 INNER JOIN s2 ON s1.key1=s2.key1 WHERE s1.common_field='a';

在这里插入图片描述
从执行计划中可以看出,查询优化器打算把s1当做驱动表,s2当做被驱动表,我们可以看到驱动表s1表的执行计划的rows列为9895,filtered列为10.00, 这意味着驱动表s1的扇出值就是9895*0.1=989.6,这说明还要对被驱动表执行大概989次查询。

6. Extra

顾名思义,Extra列是用来说明一些额外信息的,包含不适合在其他列中显示但十分重要的额外信息,我们可以通过这些额外信息来更准确的理解MySQL到底将如何执行给定的查询语句。MySQL提供的额外信息有好几十个,我们就不一个个介绍了,所以我们只挑选比较重要的额外信息。

6.1. No tables used

当查询语句的没有FROM子句时将会提示该额外信息,比如:

EXPLAIN SELECT 1;

在这里插入图片描述

6.2. Using where

当我们使用全表扫描来执行对某个表的查询,并且该语句的WHERE 子句中有针对该表的搜索条件时,在Extra 列中会提示上述额外信息。

EXPLAIN SELECT * FROM s1 WHERE common_field='a';

在这里插入图片描述
当使用索引访问来执行对某个表的查询,并且该语句的WHERE 子句中,有除了该索引包含的列之外的其他搜素条件时。在Extra 列中也会提示上述额外信息。

EXPLAIN SELECT * FROM s1 WHERE key1='a' AND common_field='a';

在这里插入图片描述

6.3. Using index

当我们的查询列表以及搜索条件中只包含属于某个索引的列,也就是在可以使用覆盖索引的情况下,在Extra 列将会提示该额外信息,比方说下边这个查询中只需要使用到idx_key1 而不需要回表操作

EXPLAIN SELECT key1 FROM s1 WHERE key1='a';

在这里插入图片描述

6.4. Using index condition

有些搜索条件中虽然出现了索引列,但却不能使用到索引

EXPLAIN SELECT * FROM s1 WHERE key1>'z' AND key1 LIKE '%a';

在这里插入图片描述
这里根据key1>'z' 的条件预估会找出398条记录,然后在根据主键id 到聚簇索引中去进行回表操作。如果使用 Using index condition 的话在会在回表之前先从398条记录中筛选满足 key1 LIKE '%a' 的记录,再去进行回表操作。

6.5. Using join buffer (Block Nested Loop)

在连接查询执行过程中,当被驱动表不能有效的利用索引加快访问速度,MySQL一般会为其分配一块名叫join buffer 的内存块来加快查询速度,也就是我们所讲的基于块的嵌套循环算法
在这里插入图片描述

6.6. Not exists

当我们使用左(外)连接时,如果WHERE 子句中包含要求被驱动表的某个列等于NULL 值的搜索条件,而且那个列又是不允许存储NULL值的,那么在该表的执行计划的Extra列就会提示Not exists 额外信息。

EXPLAIN SELECT * FROM s1 LEFT JOIN s2 ON s1.key1=s2.key1 WHERE s2.id IS NULL;

在这里插入图片描述

6.7. Using union

如果执行计划的Extra 列出现了Using intersect(…) 提示,说明准备使用Intersect 索引合并的方式执行查询,括号中的**…** 表示需要进行索引合并的索引名称;如果出现Using union(…) 提示,说明准备使用Union 索引合并的方式执行查询,出现了Using sort_union(…) 提示,说明准备使用Sort-Union 索引合并的方式执行查询。

EXPLAIN SELECT * FROM s1 WHERE key1='a' OR key3='a';

在这里插入图片描述

6.8. Using filesort

有一些情况下对结果集中的记录进行排序是可以使用到索引的,比如下边这个查询:

EXPLAIN SELECT * FROM s1 ORDER BY key1 LIMIT 10;

在这里插入图片描述
这个查询语句可以利用 idx_key1 索引直接取出key1列的10条记录,然后在进行回表操作就好了,但是很多情况下排序操作无法使用到索引,只能在内存中(记录较少的时候)或者磁盘中(记录较多的时候)进行排序,MySQL把这种内存中或者磁盘上进行排序的方式统称为文件排序(英文名:filesort)。如果某个查询需要使用文件排序的方式执行查询,就会在执行计划的Extra列中显示Using filesort 提示,如果这样:

EXPLAIN SELECT * FROM s1 ORDER BY common_field LIMIT 10;

在这里插入图片描述

6.9. Using temporary

在许多查询的执行过程中,MySQL可能会借助临时表来完成一些功能,比如去重,排序之类的,比如我们在执行许多包含DISTINCT、GROUP BY、UNION等子句的查询过程中,如果不能有效利用索引来完成查询,MySQL很有可能寻求通过建立内部的临时表来执行查询。如果查询中使用到了内部的临时表,在执行计划的Extra 列将会显示Using temporary 提示

EXPLAIN SELECT DISTINCT common_field FROM s1;
EXPLAIN SELECT common_field,COUNT(*) AS amount FROM s1 GROUP BY common_field;

在这里插入图片描述
执行计划中出现Using temporary 并不是一个好的征兆,因为建立与维护临时表要付出很大成本的,所以我们最好能使用索引来替换掉使用临时表,比如:扫描指定的索引 idx_key1即可。

EXPLAIN SELECT key1,COUNT(*) AS amount FROM s1 GROUP BY key1;

在这里插入图片描述
从Extra的Using index 的提示里我们可以看出,上述查询只需要扫描idx_key1 索引就可以搞定了,不再需要临时表了。

6.10 小结

  1. EXPLAIN 不考虑各种Cache
  2. EXPLAIN 不能显示MySQL在执行查询时所作的优化工作
  3. EXPLAIN不会告诉你关于触发器,存储过程的信息或用户自定义函数对查询的影响情况
  4. 部分统计信息是估算的,并非精确值。

7. EXPLAIN 四种输出格式

EXPLAIN可以输出四种格式:传统格式、JSON格式、TREE格式以及可视化输出。用户可以根据需要选择适用于自己的格式。

7.1. 传统格式

传统格式简单明了,输出是一个表格形式,概要说明查询计划
在这里插入图片描述

7.2. JSON格式

第一种格式中介绍的EXPLAIN语句输出中缺少了一个衡量执行计划好坏的重要属性–成本,而JSON格式是四种格式里面输出信息最详尽的格式,里面包含了执行的成本信息。

JSON格式:在EXPLAIN单词和真正的查询语句中间加上FORMAT=JSON

EXPLAIN FORMAT=JSON SELECT ....

EXPLAIN 的Column与JSON的对应关系:(来源于MySQL 5.7文档)

ColumnJSON NameMeaning
idselect_idThe Select identifier
select_typeNoneThe SELECT type
tabletable_nameThe table for the output row
partitionspartitionsThe matching partitions
typeaccess_typeThe join type
possible_keyspossible_keysThe possible indexes to choose
keykeyThe index actually chosen
key_lenkey_lengthThe length of the chosen key
refrefThe columns compared to the index
rowsrowsEstimate of rows to be examined
filteredfilteredPercentage of rows filtered by table condition
ExtraNoneAdditional information
这样我们就可以得到一个json格式的执行计划,里面包含该计划花费的成本,比如这样:
EXPLAIN FORMAT=JSON SELECT * FROM s1 \G;

在这里插入图片描述
其中:"query_cost": "2076.00" 表示总的查询成本。s1表的"cost_info"部分:

 "cost_info": {
        "read_cost": "97.00",
        "eval_cost": "1979.00",
        "prefix_cost": "2076.00",
        "data_read_per_join": "17M"
      }
  • read_cost 是由下边这两部分组成的:
    IO成本
    检测rows*(1-filtered)条记录的CPU成本
  • eval_cost 是这样计算的:
    检测 rows*filtered 条记录的成本。
  • prefix_cost 就是单独查询s1表的成本,也就是:read_cost+eval_cost
  • data_read_per_join 表示在此次查询中需要读取的数据量。

8. 总结

本文详细介绍了EXPLAIN中ref、rows、filtered、Extra字段的剖析,其中rows字段和Extra字段非常的重要,另外EXPLAIN有四种输出格式,其中JSON格式可以列出查询的执行成本。

相关文章:

  • C语言数组详解
  • DS | 冲刺阶段考点整理 —— 绪论、线性表、栈与队列、特殊矩阵、串
  • 实验5 循环结构
  • 【漏洞复现-Apache-目录穿越文件读取-RCE】vulfocus/apache(cve_2021_41773)
  • 基于matlab的SVM支持向量机分类仿真,核函数采用RBF函数(提供matlab仿真录像)
  • 机器学习基础:拉格朗日乘子法
  • Matlab 与 Python 基于窗函数的滤波器设计对比 之 凯瑟窗
  • java web开发(从spring boot到spring cloud)
  • 看呆了!二面高德 Java 岗,问了一堆源码,微服务,分布式,Redis,心累
  • 2022华为杯研究生数学建模竞赛B题思路解析
  • 2022华为杯研究生数学建模竞赛E题思路解析
  • 【C语言】学生考勤管理系统
  • 常用的调试技巧(如何检测bug)
  • SpringBoot二十六课大纲和目录
  • 2022年中国研究生数学建模竞赛C题-汽车制造涂装-总装缓存调序区调度优化问题
  • [PHP内核探索]PHP中的哈希表
  • [译]Python中的类属性与实例属性的区别
  • 2017-09-12 前端日报
  • 8年软件测试工程师感悟——写给还在迷茫中的朋友
  • C++回声服务器_9-epoll边缘触发模式版本服务器
  • Fastjson的基本使用方法大全
  • IDEA常用插件整理
  • Java编程基础24——递归练习
  • jQuery(一)
  • JSDuck 与 AngularJS 融合技巧
  • JS题目及答案整理
  • JS正则表达式精简教程(JavaScript RegExp 对象)
  • Redis 懒删除(lazy free)简史
  • VuePress 静态网站生成
  • 从PHP迁移至Golang - 基础篇
  • 湖南卫视:中国白领因网络偷菜成当代最寂寞的人?
  • 讲清楚之javascript作用域
  • 精益 React 学习指南 (Lean React)- 1.5 React 与 DOM
  • 理解 C# 泛型接口中的协变与逆变(抗变)
  • 力扣(LeetCode)22
  • 你不可错过的前端面试题(一)
  • 设计模式走一遍---观察者模式
  • d²y/dx²; 偏导数问题 请问f1 f2是什么意思
  • ​​​​​​​Installing ROS on the Raspberry Pi
  • #100天计划# 2013年9月29日
  • #1015 : KMP算法
  • (26)4.7 字符函数和字符串函数
  • (第9篇)大数据的的超级应用——数据挖掘-推荐系统
  • (附源码)springboot“微印象”在线打印预约系统 毕业设计 061642
  • (附源码)ssm户外用品商城 毕业设计 112346
  • (接口自动化)Python3操作MySQL数据库
  • (十六)Flask之蓝图
  • (十六)一篇文章学会Java的常用API
  • (学习日记)2024.02.29:UCOSIII第二节
  • (转载)跟我一起学习VIM - The Life Changing Editor
  • (自用)learnOpenGL学习总结-高级OpenGL-抗锯齿
  • ****** 二 ******、软设笔记【数据结构】-KMP算法、树、二叉树
  • ./configure,make,make install的作用
  • .helper勒索病毒的最新威胁:如何恢复您的数据?
  • .MyFile@waifu.club.wis.mkp勒索病毒数据怎么处理|数据解密恢复