2015-06-19 59 views
4

我想在PostgreSQL上創建一個存儲函數來提高性能並存儲大的查詢,並且只需在我的代碼中調用該函數。PostgreSQL性能 - 選擇vs存儲功能

舉例來說,如果我有一個函數:

CREATE OR REPLACE FUNCTION test(max integer) 
RETURNS TABLE (id integer) AS $$ 
SELECT User.id 
FROM User 
LIMIT max; 
$$ LANGUAGE sql STABLE; 

我把這樣的功能查看查詢的時間:

EXPLAIN ANALYZE SELECT test(10); 

而且功能遠遠比同慢原始的SQL查詢!我認爲存儲功能將在創建時編譯和優化。如果我嘗試使用更大的查詢,則使用函數的性能會很糟糕。

我想我可能做錯了什麼!

謝謝

+0

什麼是較大的查詢?.. –

回答

8

企劃與您的查詢,因爲它無法評估函數的執行時間的問題。在這種情況下,計劃者獲得該函數的估計執行成本,該成本可以在create function...alter function...中定義。但是,如果您嘗試此查詢:

explain analyse select * from test(10); 

您會看到執行時間更爲現實。

比較:

test=# explain analyse select test(1000); 
             QUERY PLAN 
------------------------------------------------------------------------------------------ 
Result (cost=0.00..5.25 rows=1000 width=0) (actual time=0.830..1.220 rows=1000 loops=1) 
Planning time: 0.038 ms 
Execution time: 1.250 ms 
(3 rows) 

與:

test=# explain analyse select * from test(1000); 
                QUERY PLAN 
---------------------------------------------------------------------------------------------------------------- 
Limit (cost=0.00..37.42 rows=1000 width=4) (actual time=0.006..0.124 rows=1000 loops=1) 
    -> Seq Scan on test_table (cost=0.00..2560.28 rows=68428 width=4) (actual time=0.005..0.102 rows=1000 loops=1) 
Planning time: 0.130 ms 
Execution time: 0.144 ms 
(4 rows) 


test=# explain analyse select * from test_table limit 1000; 
                QUERY PLAN 
------------------------------------------------------------------------------------------------------------------ 
Limit (cost=0.00..37.42 rows=1000 width=269) (actual time=0.009..0.118 rows=1000 loops=1) 
    -> Seq Scan on test_table (cost=0.00..2560.28 rows=68428 width=269) (actual time=0.008..0.097 rows=1000 loops=1) 
Planning time: 0.076 ms 
Execution time: 0.151 ms 
(4 rows) 

注的最後兩個計劃相似。應該在FROM子句中調用表函數(在這種情況下返回一組行或表的函數)。在某些情況下,他們可以內聯。

瞭解更多:Inlining of SQL functions

+0

非常感謝,它的工作完美:) – Oubord