【发布时间】:2015-01-30 21:34:59
【问题描述】:
这个问题是SQL function very slow compared to query without function wrapper 的后续问题和结果。我应该注意,我不认为这是重复的,因为该问题是要求解决特定问题。我在这里询问有关一般行为的更多信息,并演示如何复制它。 (为了证明差异,您可以在我们讨论该行为的已接受答案上看到相当长的评论线程,我觉得它离题了,特别是考虑到长度。)
我有一个功能。以下是展示感兴趣行为的示例:
CREATE OR REPLACE FUNCTION test(INT)
RETURNS TABLE(num INT, letter TEXT)
VOLATILE
LANGUAGE SQL
AS $$
SELECT *
FROM (VALUES (1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e')) x
LIMIT $1
$$;
当我运行这个EXPLAIN:
EXPLAIN ANALYZE SELECT * FROM test(10);
我在 psql 中得到了这个结果(我已经删除了一个巨大的“查询计划”标题):
Function Scan on test (cost=0.25..10.25 rows=1000 width=36) (actual time=0.125..0.136 rows=5 loops=1)
Total runtime: 0.179 ms
(2 rows)
注意行估计。它估计有 1000 行。
但是,如果我将函数更改为STABLE 或IMMUTABLE:
CREATE OR REPLACE FUNCTION test(INT)
RETURNS TABLE(num INT, letter TEXT)
STABLE
LANGUAGE SQL
AS $$
SELECT *
FROM (VALUES (1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e')) x
LIMIT $1
$$;
那么同一个EXPLAIN给了我一个不同的方案:
Limit (cost=0.00..0.06 rows=5 width=36) (actual time=0.010..0.050 rows=5 loops=1)
-> Values Scan on "*VALUES*" (cost=0.00..0.06 rows=5 width=36) (actual time=0.005..0.018 rows=5 loops=1)
Total runtime: 0.087 ms
(3 rows)
现在它正确估计了 5 行,并显示了函数内包含的查询计划。成本要高一个数量级。运行时间也下降了。 (查询很短,可能不是特别重要。)
鉴于链接的问题处理更多数据并具有非常显着的性能差异,根据函数是VOLATILE 还是STABLE/IMMUTABLE,规划器实际上正在做不同的事情.
计划者在这里具体做什么,我在哪里可以阅读有关它的一些文档?
这些测试在 PG 9.3 中运行。
【问题讨论】:
标签: postgresql function volatile sql-execution-plan