这条命令显示PostgreSQL规划器为所提供的查询生成的执行规划。 执行规划显示查询引用的表是如何被扫描的--- 是简单的顺序扫描,还是 索引扫描等 --- 并且如果引用了多个表, 采用了什么样的连接算法从每个输入的表中取出所需要的记录。
显示出来的最关键的部分是预计的查询执行开销, 这就是规划器对运行该查询所需时间的估计(以磁盘页面存取为单位计量)。 实际上显示了两个数字:返回第一条记录前的启动时间, 和返回所有记录的总时间。对于大多数查询而言,关心的是总时间,但是, 在某些环境下,比如一个 EXISTS 子查询里, 规划器将选择最小启动时间而不是最小总时间 (因为执行器在获取一条记录后总是要停下来)。同样, 如果你用一条 LIMIT 子句限制返回的记录数, 规划器会在最终的开销上做一个合理的插值以计算哪个规划开销最省。
ANALYZE 选项导致查询被实际执行,而不仅仅是规划. 它在显示中增加了 在每个规划节点内部花掉的总时间(以毫秒计)和它实际返回的行数. 这些数据对搜索该规划器的预期是否和现实相近很有帮助.
Caution |
要记住的是查询实际上在使用 ANALYZE 的时候是执行的. 尽管 EXPLAIN 会抛弃任何 SELECT 会返回的输出, 但是其它查询的副作用还是一样会发生的. 如果你在 INSERT,UPDATE,或者 DELETE 查询里使用 EXPLAIN ANALYZE,而且还不想让查询影响你的数据, 用下面的方法∶ BEGIN; EXPLAIN ANALYZE ...; ROLLBACK;
|
VERBOSE 选项输出规划树在系统内部的完整内容, 而不仅仅是一个概要. 通常这个选项只是对调试PostgreSQL有用。 VERBOSE 转储的格式可能易读,也可能不易读, 取决于配置参数 EXPLAIN_PRETTY_PRINT 的设置.
显示一个对只有一个 int4 列和 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 < 4; 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)
注意这里显示的数字, 甚至还有选择的查询策略都有可能在各个 PostgreSQL版本之间不同--因为规划器在不断改进。