↑↓ 选择 ↵ 打开 ⌫ 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
测试与开发版本: 19 / devel
不受支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2 / 7.1 / 7.0 / 6.5 / 6.4
历史版本PostgreSQL 8.2 已于 2011 年 12 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本。

EXPLAIN

EXPLAIN — 显示一个语句的执行计划

大纲

EXPLAIN [ ANALYZE ] [ VERBOSE ] statement

描述

这个命令显示PostgreSQL规划器为给定语句生成的执行计划。执行计划会显示将如何扫描该语句引用的表 — 例如普通顺序扫描、索引扫描等 —,如果引用了多个表,还会显示将使用哪些连接算法来汇集每个输入表中的所需行。

显示结果中最关键的部分是语句执行代价的估计值,它是规划器对运行该语句需要多长时间的猜测(以磁盘页面抓取次数为单位衡量)。实际上会显示两个数字:返回第一行之前的启动代价,以及返回全部行的总代价。对大多数查询来说,总代价才是关键;但在某些场景中,例如EXISTS中的子查询,规划器会选择启动代价最小而不是总代价最小的计划(因为无论如何执行器都会在得到一行后停止)。此外,如果你用LIMIT子句限制返回的行数,规划器会在端点代价之间作适当插值,以估计哪个计划实际上最便宜。

ANALYZE 选项导致语句被真正执行,而不仅仅是规划。每个计划节点内部耗费的总时间(以毫秒计)以及它实际返回的总行数会被加入显示。这有助于查看规划器的估计是否接近现实。

重要

请记住,使用 ANALYZE 选项时,语句会被实际执行。虽然 EXPLAIN 会丢弃 SELECT 返回的任何输出,但语句的其他副作用仍会照常发生。如果希望使用 EXPLAIN ANALYZE 分析 INSERT, UPDATE, DELETE或EXECUTE语句而不让命令影响数据,可以采用以下方法:

BEGIN;
EXPLAIN ANALYZE ...;
ROLLBACK;

参数

ANALYZE

执行命令并显示实际的运行时间。

VERBOSE

显示计划树的完整内部表示,而不是只显示摘要。通常此选项只对专门的 调试目的有用。VERBOSE输出是否进行美化打印,取决 于explain_pretty_print配置参数的设置。

statement

任何你希望查看其执行计划的SELECT、INSERT、UPDATE、DELETE、VALUES、EXECUTE或DECLARE语句。

注解

关于 PostgreSQL 中优化器对代价信息的使用,文档很少。更多信息参见 第 13.1 节。

为了让 PostgreSQL 查询规划器在优化查询时能做出合理知情的决定,应当运行ANALYZE语句来记录表中数据分布的统计信息。如果你没有这样做(或者自上次运行 ANALYZE 以来表中数据的统计分布发生了显著变化),估计的代价不太可能符合查询的真实属性,因此可能选出一个较差的查询计划。

遗传查询优化(GEQO)随机测试执行计划。因此,当表的数量超过geqo_threshold从而启用遗传查询优化时,每次执行该语句时执行计划都很可能发生变化。

示例

要显示一个只有单个integer列且包含 10000 行的表上的简单查询计划:

EXPLAIN SELECT * FROM foo;

                       QUERY PLAN
---------------------------------------------------------
 Seq Scan on foo  (cost=0.00..155.00 rows=10000 width=4)
(1 row)

如果存在索引,并且我们使用了带有可索引WHERE条件的查询,EXPLAIN可能会显示不同的计划:

EXPLAIN SELECT * FROM foo WHERE i = 4;

                         QUERY PLAN
--------------------------------------------------------------
 Index Scan using fi on foo  (cost=0.00..5.98 rows=1 width=4)
   Index Cond: (i = 4)
(2 rows)

下面是使用聚合函数的查询的查询计划示例:

EXPLAIN SELECT sum(i) FROM foo WHERE i < 10;

                             QUERY PLAN
---------------------------------------------------------------------
 Aggregate  (cost=23.93..23.93 rows=1 width=4)
   ->  Index Scan using fi on foo  (cost=0.00..23.92 rows=6 width=4)
         Index Cond: (i < 10)
(3 rows)

下面是使用 EXPLAIN EXECUTE 显示预备查询执行计划的示例:

PREPARE query(int, int) AS SELECT sum(bar) FROM test
    WHERE id > $1 AND id < $2
    GROUP BY foo;

EXPLAIN ANALYZE EXECUTE query(100, 200);

                                                       QUERY PLAN                                                        
-------------------------------------------------------------------------------------------------------------------------
 HashAggregate  (cost=39.53..39.53 rows=1 width=8) (actual time=0.661..0.672 rows=7 loops=1)
   ->  Index Scan using test_pkey on test  (cost=0.00..32.97 rows=1311 width=8) (actual time=0.050..0.395 rows=99 loops=1)
         Index Cond: ((id > $1) AND (id < $2))
 Total runtime: 0.851 ms
(4 rows)

当然,这里显示的具体数字取决于所涉及表的实际内容。还要注意,由于规划器的改进,这些数字甚至所选查询策略在PostgreSQL的不同版本之间都可能发生变化。此外,ANALYZE命令使用随机采样来估计数据统计信息;因此,即使表中数据的实际分布没有变化,在重新运行一次ANALYZE之后,代价估计也可能发生变化。

兼容性

SQL 标准中没有定义EXPLAIN语句。

另见

ANALYZE

提交更正

译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。