PostgreSQL 的 EXPLAIN ANALYZE 的 MySQL 等价物是啥

Posted

技术标签:

【中文标题】PostgreSQL 的 EXPLAIN ANALYZE 的 MySQL 等价物是啥【英文标题】:What is the MySQL equivalent of PostgreSQL's EXPLAIN ANALYZEPostgreSQL 的 EXPLAIN ANALYZE 的 MySQL 等价物是什么 【发布时间】:2011-10-12 08:42:28 【问题描述】:

我想在 mysql 中获得一个详细的查询计划,类似于 PostgreSQL 中的 EXPLAIN ANALYZE 显示。有没有等价物?

【问题讨论】:

【参考方案1】:

编辑:虽然不是直接等价物或与解释分析一样详细,但您可以查看一些工具

mysql提供EXPLAIN和procedure analyse()http://dev.mysql.com/doc/refman/5.0/en/explain.htmlhttp://dev.mysql.com/doc/refman/5.0/en/procedure-analyse.html

【讨论】:

虽然 MySQL 的解释会返回一个执行计划,但它绝不像 PostgreSQL 从 EXPLAIN ANALZYE 的输出那样详细。我认为 MySQL 中没有任何东西会给出如此详细的计划。 我同意马的观点,没有真正的等价物。我认为您必须打开某种扩展统计信息并运行查询,然后使用解释的输出和日志才能真正得到类似的结果。【参考方案2】:

在 MySQL 拥有 EXPLAIN EXTENDED 之前我没有使用过 PostgreSQL,它提供的信息比 EXPLAIN 更多,并且可能会为您提供您正在寻找的信息。

【讨论】:

【参考方案3】:

EXPLAIN EXTENDED

MariaDB/MySQL 提供了一个叫做EXPLAIN EXTENDED 的东西。但是,EXPLAIN ANALYZE 是无可替代的。 EXPLAIN EXTENDED 不提供任何时间信息,内部故障也没有那么冗长。

Name: 'EXPLAIN'
Description:
Syntax:
EXPLAIN [explain_type] SELECT select_options

explain_type:
    EXTENDED
  | PARTITIONS

Or:

EXPLAIN tbl_name

The EXPLAIN statement can be used either as a way to obtain information
about how MySQL executes a statement, or as a synonym for DESCRIBE:

o When you precede a SELECT statement with the keyword EXPLAIN, MySQL
  displays information from the optimizer about the query execution
  plan. That is, MySQL explains how it would process the statement,
  including information about how tables are joined and in which order.
  EXPLAIN EXTENDED can be used to obtain additional information.

  For information about using EXPLAIN and EXPLAIN EXTENDED to obtain
  query execution plan information, see
  https://mariadb.com/kb/en/explain/.

o EXPLAIN PARTITIONS is useful only when examining queries involving
  partitioned tables. For details, see
  http://dev.mysql.com/doc/refman/5.5/en/partitioning-info.html.

o EXPLAIN tbl_name is synonymous with DESCRIBE tbl_name or SHOW COLUMNS
  FROM tbl_name. For information about DESCRIBE and SHOW COLUMNS, see
  [HELP DESCRIBE], and [HELP SHOW COLUMNS].

URL: https://mariadb.com/kb/en/explain/

例如这是taken from this example,

EXPLAIN ANALYZE SELECT *
FROM history AS h1
WHERE EXISTS (
  SELECT 1
  FROM history AS h2
  WHERE h1.lead_id = h2.lead_id
  GROUP BY lead_id
  HAVING count(is_first OR NULL) > 1
);

会在 PostgreSQL 上产生类似的东西,

                                                     QUERY PLAN                                                     
--------------------------------------------------------------------------------------------------------------------
 Seq Scan on history h1  (cost=0.00..82680.50 rows=1100 width=9) (actual time=0.048..0.065 rows=3 loops=1)
   Filter: (SubPlan 1)
   Rows Removed by Filter: 3
   SubPlan 1
     ->  GroupAggregate  (cost=0.00..37.57 rows=1 width=5) (actual time=0.007..0.007 rows=0 loops=6)
           Group Key: h2.lead_id
           Filter: (count((h2.is_first OR NULL::boolean)) > 1)
           Rows Removed by Filter: 0
           ->  Seq Scan on history h2  (cost=0.00..37.50 rows=11 width=5) (actual time=0.003..0.004 rows=2 loops=6)
                 Filter: (h1.lead_id = lead_id)
                 Rows Removed by Filter: 4
 Planning time: 0.149 ms
 Execution time: 0.123 ms
(13 rows)

虽然这是 MySQL 的等价物,但

+------+--------------------+-------+------+---------------+------+---------+------+------+----------+-------------+
| id   | select_type        | table | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+------+--------------------+-------+------+---------------+------+---------+------+------+----------+-------------+
|    1 | PRIMARY            | h1    | ALL  | NULL          | NULL | NULL    | NULL |    6 |   100.00 | Using where |
|    2 | DEPENDENT SUBQUERY | h2    | ALL  | NULL          | NULL | NULL    | NULL |    6 |   100.00 | Using where |
+------+--------------------+-------+------+---------------+------+---------+------+------+----------+-------------+
2 rows in set, 2 warnings (0.00 sec)

【讨论】:

小更新 MySQL 5.7+/MariaDB 10.1.2+ 有EXPLAIN FORMAT=JSON,其中包括相对查询成本。MySQL 5.6.3+ 还可以选择跟踪优化器 (dev.mysql.com/doc/internals/en/tracing-example.html),其中有些方法可以作为PostgreSQL的EXPLAIN ANALYZE 根据 MySQL 文档,EXPLAIN EXTENDED 不再有任何好处:“在较旧的 MySQL 版本中,分区和扩展信息是使用 EXPLAIN PARTITIONS 和 EXPLAIN EXTENDED 生成的。这些语法仍然被认为具有向后兼容性,但现在默认启用分区和扩展输出,因此 PARTITIONS 和 EXTENDED 关键字是多余的并且已弃用。它们的使用会导致警告,并且它们将在未来的 MySQL 版本中从 EXPLAIN 语法中删除。"【参考方案4】:

MySQL 8.0.18 原生引入EXPLAIN ANALYZE:

MySQL 8.0.18 引入了 EXPLAIN ANALYZE,它运行查询并生成 EXPLAIN 输出以及时间和其他基于迭代器的关于优化器的期望如何匹配实际执行的信息。对于每个迭代器,提供以下信息:

预计执行成本

估计返回的行数

是时候返回第一行了

返回所有行的时间(实际成本)

迭代器返回的行数

循环次数

EXPLAIN ANALYZE 只能用于 SELECT 语句。

【讨论】:

【参考方案5】:

为了清楚起见,评论接受的答案(没有足够的业力来添加评论)

procedure analyse() 用于解释的不同目的, 它分析指定列的数据集并建议最佳数据类型, 也就是说,当我们有 1000 行 varchar(255) 并且想要检查我们真正需要多少长度时,它很有用,例如它可能表明 varchar(23) 就足够了

【讨论】:

【参考方案6】:

2020 年更新 EXPLAIN ANALYZE 可用

旧问题,但只是为了更新,8.0.18 版本Explain Analyze 也可以在MySQL 中使用,您可以像下面这样使用它:

mysql> explain analyze select count(*) from sbtest1 where k > 500000\G
*************************** 1. row ***************************
EXPLAIN: -> Aggregate: count(0) (actual time=178.225..178.225 rows=1 loops=1)
-> Filter: (sbtest1.k > 500000) (cost=98896.53 rows=493204) (actual time=0.022..147.502 rows=625262 loops=1)
-> Index range scan on sbtest1 using idx3 (cost=98896.53 rows=493204) (actual time=0.021..96.488 rows=625262 loops=1)

1 row in set (0.18 sec)

【讨论】:

以上是关于PostgreSQL 的 EXPLAIN ANALYZE 的 MySQL 等价物是啥的主要内容,如果未能解决你的问题,请参考以下文章

PostgreSQL EXPLAIN ANALYZE 的 MySQL 等价物是啥

PostgreSQL学习系列—EXPLAIN ANALYZE查询计划解读

pg_flame postgresql EXPLAIN ANALYZE 火焰图工具

postgresql中执行计划

使用 Drill 查询获取 PostgreSQL 执行计划

如何优化在 postgresql 中查询这些数据?