共计 3563 个字符,预计需要花费 9 分钟才能阅读完成。
自动写代码机器人,免费开通
这篇文章主要介绍 MySql 中怎么使用 explain 查询 SQL 的执行计划,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!
explain 命令是查看查询优化器如何决定执行查询的主要方法。
这个功能有局限性,并不总会说出真相,但它的输出是可以获取的最好信息,值得花时间去了解,因为可以学习到查询是如何执行的。
1、什么是 MySQL 执行计划
要对执行计划有个比较好的理解,需要先对 MySQL 的基础结构及查询基本原理有简单的了解。
MySQL 本身的功能架构分为三个部分,分别是 应用层、逻辑层、物理层,不只是 MySQL,其他大多数数据库产品都是按这种架构来进行划分的。
应用层,主要负责与客户端进行交互,建立链接,记住链接状态,返回数据,响应请求,这一层是和客户端打交道的。
逻辑层,主要负责查询处理、事务管理等其他数据库功能处理,以查询为例。
首先接收到查询 SQL 之后,数据库会立即分配一个线程对其进行处理,第一步查询处理器会对 SQL 查询进行优化,优化后会生成执行计划,然后交由计划执行器来执行。
计划执行器需要访问更底层的事务管理器,存储管理器来操作数据,他们各自的分工各有不同,最终通过调用物理层的文件获取到查询结构信息,将最终结果响应给应用层。
物理层,实际物理磁盘上存储的文件,主要有分文数据文件,日志文件。
通过上面的描述,生成执行计划是执行一条 SQL 必不可少的步骤,一条 SQL 性能的好坏,可以通过查看执行计划很直观的看出来,执行计划提供了各种查询类型与级别,方面我们进行查看以及为作为性能分析的依据。
2、如何分析执行计划
MySQL 为我们提供了 explain 关键字来直观的查看一条 SQL 的执行计划。
explain 显示了 MySQL 如何使用索引来处理 select 语句以及连接表,可以帮助选择更好的索引和写出更优化的查询语句。
下面我们使用 explain 做一个查询,如下:
mysql explain select * from payment;
+----+-------------+---------+------------+------+---------------+------+---------+------+-------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+---------+------------+------+---------------+------+---------+------+-------+----------+-------+
| 1 | SIMPLE | payment | NULL | ALL | NULL | NULL | NULL | NULL | 16086 | 100.00 | NULL |
+----+-------------+---------+------------+------+---------------+------+---------+------+-------+----------+-------+
1 row in set, 1 warning (0.01 sec)
查询结构中有 12 列,理解每一列的含义,对理解执行计划至关重要,下面用一个表格的形式进行说明。
列名说明 idSELECT 识别符,这是 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 的执行计划”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注丸趣 TV 行业资讯频道!
向 AI 问一下细节