我正在尝试了解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
如果我取消注释部分并注释掉以解释分析,该函数将正常工作。
或者您可以将此简单形式与RETURN QUERY
一起使用:
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;
在Postgres 9.3中为我工作。
任何查询都必须在plpgsql中有一个已知的目标(或者您可以使用SELECT * FROM f_explain_analyze(1);
语句丢弃结果)。所以你可以做:
PERFORM
postgres =#SELECT fx('1');注意:对foo进行Seq扫描(成本= 0.00..1.18行= 1宽度= 3)(实际时间= 0.024..0.024行= 0循环= 1)注意:过滤器:((v):: text ='1':: text)注意:筛选器删除的行数:14注意:计划时间:0.103 ms注意:总运行时间:0.065毫秒外汇────(1列)
获得嵌入式SQL计划的另一种可能性是使用准备好的语句:
postgres =#准备xx(text)AS SELECT * FROM foo WHERE v = $ 1;准备时间:0.810毫秒postgres =#解释执行xx('1');查询计划──────────────────────────────────────────── ────────────────────────────────在foo上进行Seq扫描(成本= 0.00..1.18行= 1宽度= 3)(实际时间= 0.030..0.030行= 0循环= 1)过滤器:((v):: text ='1':: text)筛选器删除的行数:14总运行时间:0.083毫秒(4列)
您可以查看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 '%', t;
END LOOP;
END;
$$ LANGUAGE plpgsql;
,并在日志文件中捕获解释。
还要查看这是否满足您的要求。 http://www.postgresql.org/docs/current/static/auto-explain.html