解释PL/pgSQL中的分析给出错误:“查询没有结果数据的目标”

解释PL/pgSQL中的分析给出错误:“查询没有结果数据的目标”,sql,postgresql,plpgsql,explain,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_fun

我试图理解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
如果我取消注释注释了注释的部分并注释了explain analyze,则该函数可以正常工作。

您可以查看并在日志文件中捕获解释


还要看看这是否符合你的要求

任何查询都必须在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 '%', t;
  END LOOP;
END;
$$ LANGUAGE plpgsql;
获取嵌入式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)
或者,您可以将此更简单的表单用于:

电话:


在Postgres 9.3中对我有效。

这个自动解释很有效,但比我的案例中公认的解决方案要费劲一些。谢谢你的回复我不知道你为什么被否决了!。这看起来是解决问题和开发新功能的一个非常好的解决方案。您的函数中可以有多个返回查询,如果您的函数有10个查询,您可以附加一个返回查询解释分析,并为每个查询返回一个解释。美好的 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)
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);