在 MySQL 中使用 explain 查询 SQL 的执行计划

2024-09-03 14:18

本文主要是介绍在 MySQL 中使用 explain 查询 SQL 的执行计划,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在 MySQL 中使用 explain 查询 SQL 的执行计划

来源:Oo若离oO

my.oschina.net/ruoli/blog/1807394

https://www.cnblogs.com/yycc/p/7338894.html

1、什么是MySQL执行计划

       

要对执行计划有个比较好的理解,需要先对MySQL的基础结构及查询基本原理有简单的了解。

        

MySQL本身的功能架构分为三个部分,分别是 应用层、逻辑层、物理层,不只是MySQL ,其他大多数数据库产品都是按这种架构来进行划分的。

 

  • 应用层,主要负责与客户端进行交互,建立链接,记住链接状态,返回数据,响应请求,这一层是和客户端打交道的。

  • 逻辑层,主要负责查询处理、事务管理等其他数据库功能处理,以查询为例。

        

首先接收到查询SQL之后,数据库会立即分配一个线程对其进行处理,第一步查询处理器会对SQL查询进行优化,优化后会生成执行计划,然后交由计划执行器来执行。

        

计划执行器需要访问更底层的事务管理器,存储管理器来操作数据,他们各自的分工各有不同,最终通过调用物理层的文件获取到查询结构信息,将最终结果响应给应用层。

 

  • 物理层,实际物理磁盘上存储的文件,主要有分文数据文件,日志文件。

   

通过上面的描述,生成执行计划是执行一条SQL必不可少的步骤,一条SQL性能的好坏,可以通过查看执行计划很直观的看出来,执行计划提供了各种查询类型与级别,方便我们进行查看以及为作为性能分析的依据。

 

2、如何分析执行计划

     

MySQL为我们提供了 explain 关键字来直观的查看一条SQL的执行计划。

     

explain显示了MySQL如何使用索引来处理select语句以及连接表,可以帮助选择更好的索引和写出更优化的查询语句。

      

下面我们使用 explain 做一个查询,如下:

 

 

查询结构中有12列,理解每一列的含义,对理解执行计划至关重要,下面进行说明。

 

id

 

SELECT识别符,这是SELECT的查询序列号。

 

select_type

 

SELECT类型,可以为以下任何一种:

 

  • SIMPLE:简单SELECT(不使用UNION或子查询)

  • PRIMARY:最外面的SELECT

  • UNION:UNION中的第二个或后面的SELECT语句

  • DEPENDENT UNION:UNION中的第二个或后面的SELECT语句,取决于外面的查询

  • UNION RESULT:UNION 的结果

  • SUBQUERY:子查询中的第一个SELECT

  • DEPENDENT SUBQUERY:子查询中的第一个SELECT,取决于外面的查询

  • DERIVED:导出表的SELECT(FROM子句的子查询)

 

table

 

输出的行所引用的表

 

partitions

 

如果查询是基于分区表的话,显示查询将访问的分区。

 

type

 

联接类型。下面给出各种联接类型,按照从最佳类型到最坏类型进行排序:

 

  • system:表仅有一行(=系统表)。这是const联接类型的一个特例。

  • const:表最多有一个匹配行,它将在查询开始时被读取。因为仅有一行,在这行的列值可被优化器剩余部分认为是常数。const表很快,因为它们只读取一次!

  • eq_ref:对于每个来自于前面的表的行组合,从该表中读取一行。这可能是最好的联接类型,除了const类型。

  • ref:对于每个来自于前面的表的行组合,所有有匹配索引值的行将从这张表中读取。

  • ref_or_null:该联接类型如同ref,但是添加了MySQL可以专门搜索包含NULL值的行。

  • index_merge:该联接类型表示使用了索引合并优化方法。

  • unique_subquery:该类型替换了下面形式的IN子查询的ref: value IN (SELECT primary_key FROM single_table WHERE some_expr) unique_subquery是一个索引查找函数,可以完全替换子查询,效率更高。

  • index_subquery:该联接类型类似于unique_subquery。可以替换IN子查询,但只适合下列形式的子查询中的非唯一索引: value IN (SELECT key_column FROM single_table WHERE some_expr)

  • range:只检索给定范围的行,使用一个索引来选择行。

  • index:该联接类型与ALL相同,除了只有索引树被扫描。这通常比ALL快,因为索引文件通常比数据文件小。

  • ALL:对于每个来自于先前的表的行组合,进行完整的表扫描,说明查询就需要优化了。

 

一般来说,得保证查询至少达到range级别,最好能达到ref。

 

possible_keys

 

指出MySQL能使用哪个索引在该表中找到行

 

key

 

显示MySQL实际决定使用的键(索引)。如果没有选择索引,键是NULL。

 

 

key_len

 

显示MySQL决定使用的键长度。如果键是NULL,则长度为NULL。在不损失精确性的情况下,长度越短越好

 

ref

 

显示使用哪个列或常数与key一起从表中选择行。

 

rows

 

显示MySQL认为它执行查询时必须检查的行数。多行之间的数据相乘可以估算要处理的行数。

 

filtered

 

显示了通过条件过滤出的行数的百分比估计值。

 

Extra

 

该列包含MySQL解决查询的详细信息

 

  • Distinct:MySQL发现第1个匹配行后,停止为当前的行组合搜索更多的行。

  • Select tables optimized away MySQL根本没有遍历表或索引就返回数据了,表示已经优化到不能再优化了

  • Not exists:MySQL能够对查询进行LEFT JOIN优化,发现1个匹配LEFT JOIN标准的行后,不再为前面的的行组合在该表内检查更多的行。

  • range checked for each record (index map: #):MySQL没有发现好的可以使用的索引,但发现如果来自前面的表的列值已知,可能部分索引可以使用。

  • Using filesort:MySQL需要额外的一次传递,以找出如何按排序顺序检索行,说明查询就需要优化了。

  • Using index:从只使用索引树中的信息而不需要进一步搜索读取实际的行来检索表中的列信息。

  • Using temporary:为了解决查询,MySQL需要创建一个临时表来容纳结果,说明查询就需要优化了。

  • Using where:WHERE 子句用于限制哪一个行匹配下一个表或发送到客户。

  • Using sort_union(…), Using union(…), Using intersect(…):这些函数说明如何为index_merge联接类型合并索引扫描。

  • Using index for group-by:类似于访问表的Using index方式,Using index for group-by表示MySQL发现了一个索引,可以用来查 询GROUP BY或DISTINCT查询的所有列,而不要额外搜索硬盘访问实际的表。

这篇关于在 MySQL 中使用 explain 查询 SQL 的执行计划的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1133188

相关文章

Java中流式并行操作parallelStream的原理和使用方法

《Java中流式并行操作parallelStream的原理和使用方法》本文详细介绍了Java中的并行流(parallelStream)的原理、正确使用方法以及在实际业务中的应用案例,并指出在使用并行流... 目录Java中流式并行操作parallelStream0. 问题的产生1. 什么是parallelS

MySQL数据库双机热备的配置方法详解

《MySQL数据库双机热备的配置方法详解》在企业级应用中,数据库的高可用性和数据的安全性是至关重要的,MySQL作为最流行的开源关系型数据库管理系统之一,提供了多种方式来实现高可用性,其中双机热备(M... 目录1. 环境准备1.1 安装mysql1.2 配置MySQL1.2.1 主服务器配置1.2.2 从

Linux join命令的使用及说明

《Linuxjoin命令的使用及说明》`join`命令用于在Linux中按字段将两个文件进行连接,类似于SQL的JOIN,它需要两个文件按用于匹配的字段排序,并且第一个文件的换行符必须是LF,`jo... 目录一. 基本语法二. 数据准备三. 指定文件的连接key四.-a输出指定文件的所有行五.-o指定输出

Linux jq命令的使用解读

《Linuxjq命令的使用解读》jq是一个强大的命令行工具,用于处理JSON数据,它可以用来查看、过滤、修改、格式化JSON数据,通过使用各种选项和过滤器,可以实现复杂的JSON处理任务... 目录一. 简介二. 选项2.1.2.2-c2.3-r2.4-R三. 字段提取3.1 普通字段3.2 数组字段四.

Linux kill正在执行的后台任务 kill进程组使用详解

《Linuxkill正在执行的后台任务kill进程组使用详解》文章介绍了两个脚本的功能和区别,以及执行这些脚本时遇到的进程管理问题,通过查看进程树、使用`kill`命令和`lsof`命令,分析了子... 目录零. 用到的命令一. 待执行的脚本二. 执行含子进程的脚本,并kill2.1 进程查看2.2 遇到的

详解SpringBoot+Ehcache使用示例

《详解SpringBoot+Ehcache使用示例》本文介绍了SpringBoot中配置Ehcache、自定义get/set方式,并实际使用缓存的过程,文中通过示例代码介绍的非常详细,对大家的学习或者... 目录摘要概念内存与磁盘持久化存储:配置灵活性:编码示例引入依赖:配置ehcache.XML文件:配置

Java 虚拟线程的创建与使用深度解析

《Java虚拟线程的创建与使用深度解析》虚拟线程是Java19中以预览特性形式引入,Java21起正式发布的轻量级线程,本文给大家介绍Java虚拟线程的创建与使用,感兴趣的朋友一起看看吧... 目录一、虚拟线程简介1.1 什么是虚拟线程?1.2 为什么需要虚拟线程?二、虚拟线程与平台线程对比代码对比示例:三

k8s按需创建PV和使用PVC详解

《k8s按需创建PV和使用PVC详解》Kubernetes中,PV和PVC用于管理持久存储,StorageClass实现动态PV分配,PVC声明存储需求并绑定PV,通过kubectl验证状态,注意回收... 目录1.按需创建 PV(使用 StorageClass)创建 StorageClass2.创建 PV

Redis 基本数据类型和使用详解

《Redis基本数据类型和使用详解》String是Redis最基本的数据类型,一个键对应一个值,它的功能十分强大,可以存储字符串、整数、浮点数等多种数据格式,本文给大家介绍Redis基本数据类型和... 目录一、Redis 入门介绍二、Redis 的五大基本数据类型2.1 String 类型2.2 Hash

深入理解Mysql OnlineDDL的算法

《深入理解MysqlOnlineDDL的算法》本文主要介绍了讲解MysqlOnlineDDL的算法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小... 目录一、Online DDL 是什么?二、Online DDL 的三种主要算法2.1COPY(复制法)