获取 PostgreSQL 中存储过程中语句的查询计划

Getting the query plan for statements inside a stored procedure in PostgreSQL

我有一个非常基本的 plpgsql 存储过程,如下所示:

create or replace procedure new_emp_sp (f_name varchar, l_name varchar, age integer, threshold integer)
language plpgsql
as $$
declare
    new_emp_count integer;
begin
    INSERT INTO employees (id, first_name, last_name, age)
        VALUES (nextval('emp_id_seq'), 
                random_string(10),
                random_string(20),
                age);
    select count(*) into new_emp_count from employees where age > threshold;
    update dept_employees set emp_count = new_emp_count where id = 'finance';
end; $$

使用 call 调用此存储过程后,如何获取该过程执行的每个语句的查询计划?

针对类似要求找到了几个 Whosebug 答案,但使用 functions 而不是使用 auto_explain 模块的过程,我按照以下步骤操作但没有成功:

  1. 已执行LOAD '$libdir/plugins/auto_explain';(我正在使用 AWS RDS PostgreSQL 实例并在 this documentation 中找到此命令)

  2. 已执行SET auto_explain.log_min_duration = 0;

  3. 已执行SET auto_explain.log_analyze = true;

  4. 已执行SET auto_explain.log_nested_statements = true;

但是执行程序后,我没有看到输出有任何明显的变化。

对于我目前的要求,我无法访问数据库服务器上的任何日志文件,并且只能通过客户端/以编程方式在服务器上运行命令

您可以将日志消息发送到客户端:

set client_min_messages TO log;

这适用于 auto_explain.log_nested_statements(无论如何在 psql 中)。我一直使用它以避免需要通过日志文件搜索。

Is this the only way of getting the query plan for a stored procedure/function?

还有一种不用安装的方法auto_explainEXPLAIN 命令基本上 returns 一组 text,您可以在 PL/pgSQL 代码块中使用它:

CREATE OR REPLACE PROCEDURE pg_temp.get_plan ()
  LANGUAGE plpgsql AS
$proc$
DECLARE
   _line text;
BEGIN
   FOR _line IN
      EXPLAIN ANALYZE
      SELECT 1            -- your query here !!!
   LOOP
      RAISE NOTICE '%', _line;
   END LOOP;
END
$proc$;

CALL pg_temp.get_plan();

您将进入您的客户端(显示通知的任何客户端):

NOTICE:  Result  (cost=0.00..0.01 rows=1 width=4) (actual time=0.004..0.005 rows=1 loops=1)
NOTICE:  Planning Time: 0.045 ms
NOTICE:  Execution Time: 0.035 ms
CALL

参见: