我试图了解PL / pgSQL函数中select语句的查询计划,但我一直在收到错误。我的问题:如何获得查询计划?
以下是一个简单的案例,可以重现问题。
有问题的表名为test_table。
CREATE TABLE test_table
(
name character varying,
id integer
);
功能如下:
DROP FUNCTION IF EXISTS test_function_1(INTEGER);
CREATE OR REPLACE FUNCTION test_function_1(inId INTEGER)
RETURNS TABLE(outName varchar)
AS
$$
BEGIN
-- is there a way to get the explain analyze output?
explain analyze select t.name from test_table t where t.id = inId;
-- return query select t.name from test_table t where t.id = inId;
END;
$$ LANGUAGE plpgsql;
当我跑步时
select * from test_function_1(10);
我收到错误:
ERROR: query has no destination for result data
CONTEXT: PL/pgSQL function test_function_1(integer) line 3 at SQL statement
如果我取消注释评论部分并注释解释分析,该功能正常。
答案 0 :(得分:7)
或者您可以将这个更简单的表单与RETURN QUERY
:
CREATE OR REPLACE FUNCTION f_explain_analyze(int)
RETURNS SETOF text AS
$func$
BEGIN
RETURN QUERY
EXPLAIN ANALYZE SELECT * FROM foo WHERE v = $1;
END
$func$ LANGUAGE plpgsql;
呼叫:
SELECT * FROM f_explain_analyze(1);
在Postgres 9.3中为我工作。
答案 1 :(得分:4)
任何查询都必须在plpgsql中有一个已知目标(或者你可以使用PERFORM
语句抛出结果)。所以你可以这样做:
CREATE OR REPLACE FUNCTION fx(text)
RETURNS void AS $$
DECLARE t text;
BEGIN
FOR t IN EXPLAIN ANALYZE SELECT * FROM foo WHERE v = $1
LOOP
RAISE NOTICE '%', r;
END LOOP;
END;
$$ LANGUAGE plpgsql;
postgres=# SELECT fx('1'); NOTICE: Seq Scan on foo (cost=0.00..1.18 rows=1 width=3) (actual time=0.024..0.024 rows=0 loops=1) NOTICE: Filter: ((v)::text = '1'::text) NOTICE: Rows Removed by Filter: 14 NOTICE: Planning time: 0.103 ms NOTICE: Total runtime: 0.065 ms fx ──── (1 row)
获得嵌入式SQL计划的另一种可能性是使用预准备语句:
postgres=# PREPARE xx(text) AS SELECT * FROM foo WHERE v = $1; PREPARE Time: 0.810 ms postgres=# EXPLAIN ANALYZE EXECUTE xx('1'); QUERY PLAN ───────────────────────────────────────────────────────────────────────────────────────────── Seq Scan on foo (cost=0.00..1.18 rows=1 width=3) (actual time=0.030..0.030 rows=0 loops=1) Filter: ((v)::text = '1'::text) Rows Removed by Filter: 14 Total runtime: 0.083 ms (4 rows)
答案 2 :(得分:1)
您可以查看http://www.postgresql.org/docs/current/static/auto-explain.html并在日志文件中捕获说明。
同时看看这是否符合您的要求。 https://github.com/pgexperts/explanation