获取 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
模块的过程,我按照以下步骤操作但没有成功:
已执行LOAD '$libdir/plugins/auto_explain';
(我正在使用 AWS RDS PostgreSQL 实例并在 this documentation 中找到此命令)
已执行SET auto_explain.log_min_duration = 0;
已执行SET auto_explain.log_analyze = true;
已执行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_explain
。 EXPLAIN
命令基本上 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
参见:
- EXPLAIN ANALYZE within PL/pgSQL gives error: "query has no destination for result data"
- Postgres query plan of a function invocation written in plpgsql
我有一个非常基本的 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
模块的过程,我按照以下步骤操作但没有成功:
已执行
LOAD '$libdir/plugins/auto_explain';
(我正在使用 AWS RDS PostgreSQL 实例并在 this documentation 中找到此命令)已执行
SET auto_explain.log_min_duration = 0;
已执行
SET auto_explain.log_analyze = true;
已执行
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_explain
。 EXPLAIN
命令基本上 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
参见:
- EXPLAIN ANALYZE within PL/pgSQL gives error: "query has no destination for result data"
- Postgres query plan of a function invocation written in plpgsql