2015-06-19 60 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