2014-02-28 36 views
3

我想了解PL/pgSQL函數中select語句的查詢計劃,但我不斷收到錯誤。我的問題:我如何獲得查詢計劃?在PL/pgSQL中解釋ANALYZE給出錯誤:「查詢沒有結果數據的目的地」

以下是重現問題的簡單情況。

問題表名爲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 

的功能,如果我取消註釋工作正常評論部分和評論ou t解釋分析。

回答

6

或者你可以使用與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。

+0

這看起來像是一個很好的解決問題和開發新功能的解決方案。你可以在你的函數中有多個RETURN QUERY,如果你有10個查詢的函數,你可以使用RETURN QUERY EXPLAIN ANALYZE來獲取每個函數的解釋。太好了! – Kuberchaun

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) 
相關問題