我运行了一些查询以获取执行时间
输入查询
explain analyze SELECT * FROM employee emp where emp.empid = ' 00010 ';
输出结果
"Seq Scan on employee emp (cost=0.00..279.00 rows=1 width=90) (actual time=0.014..3.341 rows=1 loops=1)"
" Filter: (empid = ' 00010 '::bpchar)"
" Rows Removed by Filter: 9999"
"Planning time: 0.066 ms"
"Execution time: 3.356 ms"
然后我编写了如下函数
CREATE OR REPLACE FUNCTION test19() RETURNS TEXT AS $$
DECLARE total TEXT;
BEGIN
EXPLAIN ANALYZE into total SELECT * FROM employee emp, payroll pr where emp.empid = ' 00010 ';
RETURN total;
END;
但是当我运行函数时
输入查询
select * from test19()
输出结果
Nested Loop (cost=0.00..543.00 rows=10000 width=108) (actual time=0.022..9.311 rows=10000 loops=1)
因此,函数的输出不包含执行时间。我在功能上面犯了什么错误?
答案 0 :(得分:2)
您可以将EXPLAIN ANALYZE
的输出作为XML / JSON返回并进行解析:
CREATE OR REPLACE FUNCTION test19() RETURNS TEXT
AS $$
DECLARE total TEXT;
BEGIN
EXPLAIN (ANALYZE, TIMING, FORMAT JSON) into total SELECT 1 AS c;
RETURN ((total::jsonb)-> 0 -> 'Execution Time');
END;
$$ LANGUAGE plpgsql;
答案 1 :(得分:0)
我创建了以下函数,我不敢相信它能起作用...
CREATE OR REPLACE FUNCTION test19(query TEXT) RETURNS JSON language 'plpgsql' AS $$
DECLARE total JSON;
BEGIN
EXECUTE 'EXPLAIN (ANALYZE, FORMAT JSON) ' || query into total;
RETURN total;
END;
$$;
这是一个使用方法的示例(与我的数据库相关的查询,请替换为您自己的查询):
WITH Queries(q) AS (
VALUES ('SELECT * FROM Price'),
('SELECT * FROM Price WHERE PriceTypeIK=2 AND PriceDate > current_date - interval ''50 days''')
)
SELECT q, (test19(q)->0->'Plan'->>'Actual Total Time')::FLOAT from queries;
确保始终在回滚或保存点,回滚到保存点然后提交的事务中使用它。
编辑:最后一条评论,我意识到我没有写过:您不必只提取实际的总时间,因为我已经为其编写了函数以返回整个计划。 (使用上面的方法尝试SELECT q, test19(q) from queries
)。
答案 2 :(得分:0)
SELECT INTO
仅处理一行。
EXPLAIN返回多行,因此您的函数仅返回第一行。
如果只想提取执行时间,则可以解析Lukasz所示的JSON输出,或者需要一个循环:
create or replace function show_time(to_explain text)
returns text,
as
$$
declare
l_plan_line record;
l_line text;
begin
l_line := 1;
for l_plan_line in execute 'explain (analyze, verbose, format text)'||to_explain
loop
l_line := l_plan_line."QUERY PLAN"::text;
if l_line like 'Execution Time%' then
return l_line;
end if;
end loop;
return null;
end;
$$
language plpgsql;