How to use explain in MySql to query the execution plan of SQL

  • 2021-10-25 00:01:14
  • OfStack

The explain command is the primary way to see how the query optimizer decides to execute the query.

This feature has limitations and doesn't always tell the truth, but its output is the best information available, and it's worth the time to understand because you can learn how the query is executed.

1. What is the MySQL execution plan

A good understanding of the execution plan requires a simple understanding of the MySQL infrastructure and query fundamentals.

The functional architecture of MySQL itself is divided into three parts, namely application layer, logical layer and physical layer, not only MySQL, but most other database products are divided according to this architecture.

The application layer is mainly responsible for interacting with the client, establishing links, remembering the link status, returning data and responding to requests. This layer deals with the client.

Logic layer is mainly responsible for query processing, transaction management and other database function processing, taking query as an example.

After receiving the query SQL at first, the database will immediately allocate a thread to process it. In the first step, the query processor will optimize the SQL query, and after optimization, it will generate an execution plan, which will be executed by the plan executor.

The plan executor needs to access the lower transaction manager and storage manager to operate the data, and their respective division of labor is different. Finally, the query structure information is obtained by calling the files in the physical layer, and the final result is responded to the application layer.

Physical layer, the actual physical disk on the storage of files, mainly penny data files, log files.

Through the above description, generating an execution plan is an essential step to execute an SQL, and the performance of an SQL can be seen intuitively by looking at the execution plan. The execution plan provides various query types and levels, which we view and serve as the basis for performance analysis.

2. How to analyze the execution plan

MySQL provides us with the explain keyword to visually view an SQL execution plan.

explain shows how MySQL uses indexes to process select statements and join tables to help select better indexes and write more optimized query statements.

Let's do a query using explain, as follows:


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)

There are 12 columns in the query structure. Understanding the meaning of each column is very important to understand the execution plan. The following is explained in the form of a table.

列名 说明
id SELECT识别符,这是SELECT的查询序列号。
select_type

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

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

  • PRIMARY:最外面的SELECT

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

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

  • UNION RESULT:UNION 的结果

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

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

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

table 输出的行所引用的表
partitions 如果查询是基于分区表的话,显示查询将访问的分区。
type

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

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

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

  • eq_ref:对于每个来自于前面的表的行组合,从该表中读取1行。这可能是最好的联接类型,除了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是1个索引查找函数,可以完全替换子查询,效率更高。

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

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

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

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

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

possible_keys 指出MySQL能使用哪个索引在该表中找到行
key 显示MySQL实际决定使用的键(索引)。如果没有选择索引,键是NULL。
key_len 显示MySQL决定使用的键长度。如果键是NULL,则长度为NULL。在不损失精确性的情况下,长度越短越好
ref 显示使用哪个列或常数与key1起从表中选择行。
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需要额外的1次传递,以找出如何按排序顺序检索行,说明查询就需要优化了。

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

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

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

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

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

Summarize


Related articles: