PostgreSQL 教程: EXPLAIN

九月 24, 2023

摘要:在本教程中,您学习了如何使用 PostgreSQL 的EXPLAIN语句来显示语句的执行计划。

PostgreSQL EXPLAIN 语句简介

EXPLAIN语句返回 PostgreSQL 规划器为给定语句生成的执行计划。

EXPLAIN展示 SQL 语句涉及的表将如何通过索引扫描或顺序扫描等进行扫描,以及如果使用多个表,将使用什么样的连接算法。

EXPLAIN语句返回的最重要和最有用的信息是,返回第一行之前的起始成本以及返回完整结果集的总成本。

下面显示了EXPLAIN语句的语法:

EXPLAIN [ ( option [, ...] ) ] sql_statement;

其中option可以是以下之一:

ANALYZE [ boolean ]
VERBOSE [ boolean ]
COSTS [ boolean ]
BUFFERS [ boolean ]
TIMING [ boolean ]  
SUMMARY [ boolean ]
FORMAT { TEXT | XML | JSON | YAML }

boolean指定是否应打开或关闭所选选项。您可以使用TRUEON1来启用该选项,并使用FALSEOFF0来禁用该选项。如果省略boolean,则默认为ON

ANALYZE

ANALYZE选项会先执行sql_statement,然后在返回信息中的实际运行时统计信息,会包括每个计划节点内花费的总运行时间以及实际返回的行数。

ANALYZE语句实际上执行了 SQL 语句并丢弃了输出信息,因此,如果要分析诸如INSERTUPDATEDELETE之类的任何语句而不影响数据,则应该将EXPLAIN ANALYZE包装在事务中,如下所示:

BEGIN;
    EXPLAIN ANALYZE sql_statement;
ROLLBACK;

VERBOSE

VERBOSE参数允许您显示有关计划的附加信息。该参数默认设置为FALSE

COSTS

COSTS选项包括每个计划节点的估计启动成本和总成本,以及查询计划中的估计行数和每行的估计宽度。COSTS默认为TRUE

BUFFERS

该参数添加缓冲区使用情况信息。仅当启用ANALYZE时才能使用BUFFERS。默认情况下,BUFFERS参数设置为FALSE

TIMING

该参数在输出中包括每个节点的实际启动时间和花费时间。TIMING默认为TRUE,并且仅在启用ANALYZE时才可以使用。

SUMMARY

SUMMARY参数在查询计划之后添加摘要信息,例如总时间。请注意,当使用ANALYZE选项时,默认会包含摘要信息。

FORMAT

指定查询计划的输出格式,例如TEXTXMLJSONYAML。该参数默认设置为TEXT

PostgreSQL EXPLAIN 示例

以下语句显示了对film表进行简单查询的计划:

EXPLAIN SELECT * FROM film;

输出如下:

PostgreSQL EXPLAIN - shows plan for a simple query

以下示例显示了按特定film_id返回电影的查询计划。

EXPLAIN SELECT * FROM film WHERE film_id = 100;

这是输出:

PostgreSQL EXPLAIN - shows plan for a query with an index

由于已在film_id列建立索引,该语句返回了不同的计划。在输出中,规划器使用索引扫描而不是对film表进行顺序扫描。

为了省略成本信息,您可以使用以下COSTS选项:

EXPLAIN (COSTS FALSE) SELECT
    *
FROM
    film
WHERE
    film_id = 100;

PostgreSQL EXPLAIN - shows plan without costs

以下示例显示使用聚合函数的查询计划:

EXPLAIN SELECT COUNT(*) FROM film;

输出是:

PostgreSQL EXPLAIN - shows plan with an aggregate function

以下示例返回连接多个表的语句的计划:

EXPLAIN
SELECT
    f.film_id,
    title,
    name category_name
FROM
    film f
    INNER JOIN film_category fc 
        ON fc.film_id = f.film_id
    INNER JOIN category c 
        ON c.category_id = fc.category_id
ORDER BY
    title;

输出是:

PostgreSQL EXPLAIN - shows plan for a join

要将实际运行时统计信息添加到输出中,您需要使用ANALYZE选项执行语句:

EXPLAIN ANALYZE
    SELECT
        f.film_id,
        title,
        name category_name
    FROM
        film f
        INNER JOIN film_category fc 
            ON fc.film_id = f.film_id
        INNER JOIN category c 
            ON c.category_id = fc.category_id
    ORDER BY
        title;

这是输出:

PostgreSQL EXPLAIN ANALYZE output

在本教程中,您学习了如何使用 PostgreSQL 的EXPLAIN语句来显示特定 SQL 语句的查询计划。