PL / pgSQL中的EXPLAIN ANALYZE给出错误:“查询没有结果数据的目的地”

时间:2014-02-28 16:56:29

标签: sql postgresql plpgsql explain

我试图了解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

如果我取消注释评论部分并注释解释分析,该功能正常。

3 个答案:

答案 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

相关问题