【发布时间】:2015-08-14 16:29:01
【问题描述】:
我有一个重新调整复合结果的 SQL 函数。
CREATE TYPE result_t AS (a int, b int, c int, d numeric);
CREATE OR REPLACE FUNCTION slow_function(int)
RETURNS result_t
AS $$
-- just some placeholder code to make it slow
SELECT 0, 0, 0, (
SELECT sum(ln(i::numeric))
FROM generate_series(1, $1) i
)
$$ LANGUAGE sql IMMUTABLE;
在调用函数时,我希望将复合类型的部分展开成几列。当我打电话时效果很好:
SELECT (slow_function(i)).*
FROM generate_series(0, 200) i
a b c d
---- ---- ---- --------------------
0 0 0 (null)
0 0 0 0
0 0 0 0.6931471805599453
0 0 0 1.791759469228055
...
Total runtime: 6196.754 ms
不幸的是,这会导致函数被调用每个结果列一次,这会不必要地变慢。这可以通过将运行时间与查询进行比较来测试,该查询直接返回复合结果并且运行速度提高了四倍:
SELECT slow_function(i)
FROM generate_series(0, 200) i
...
Total runtime: 1561.476 ms
示例代码也在http://sqlfiddle.com/#!15/703ba/7
如何在不浪费 CPU 资源的情况下获得包含多列的结果?
【问题讨论】:
-
The FAQ 说可以自言自语,但确实让我感到意外...
-
值得注意的是(a)
pg_sleep比“慢”函数更适合测试,并且(b)您通常可以通过使用执行 @987654327 的 PL/PgSQL 函数来了解更多信息@.
标签: sql postgresql query-optimization plpgsql