简体   繁体   English

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

[英]EXPLAIN ANALYZE within PL/pgSQL gives error: “query has no destination for result data”

I am trying to understand the query plan for a select statement within a PL/pgSQL function, but I keep getting errors.我试图了解 PL/pgSQL 函数中 select 语句的查询计划,但我不断收到错误消息。 My question: how do I get the query plan?我的问题:如何获得查询计划?

Following is a simple case that reproduces the problem.以下是重现问题的简单案例。

The table in question is named test_table.有问题的表名为 test_table。

CREATE TABLE test_table
(
  name character varying,
  id integer
);

The function is as follows:功能如下:

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;

When I run当我跑

select * from test_function_1(10);

I get the error:我收到错误:

ERROR:  query has no destination for result data
CONTEXT:  PL/pgSQL function test_function_1(integer) line 3 at SQL statement

The function works fine if I uncomment the commented portion and comment out explain analyze.如果我取消注释注释部分并注释掉解释分析,该函数工作正常。

Or you can use this simpler form with 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;

Call:称呼:

SELECT * FROM f_explain_analyze(1);

Works for me in Postgres 9.3.在 Postgres 9.3 中为我工作。

Any query has to have a known target in plpgsql (or you can throw the result away with a PERFORM statement).任何查询都必须在 plpgsql 中有一个已知目标(或者您可以使用PERFORM语句丢弃结果)。 So you can do:所以你可以这样做:

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;
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)

Another possibility to get the plan for embedded SQL is using a prepared statement:获取嵌入式 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)

You could take a look athttp://www.postgresql.org/docs/current/static/auto-explain.html and capture the explain in the log file.您可以查看http://www.postgresql.org/docs/current/static/auto-explain.html并在日志文件中捕获解释。

Also see if this does what you want.还要看看这是否符合您的要求。 https://github.com/pgexperts/explanation https://github.com/pgexperts/explanation

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM