我需要一些关于 postgres 中 plpgsql 函数的帮助。这个问题已在 psql-general 上提出,但没有确定的答案(此处和此处)
这归结为:
如何创建一个 plpgsql 函数,其中一组行作为输入,一组行作为输出,而不使用数组(为了性能)。
我目前将输入作为游标的引用传输,但它并不令人满意,因为它强制计算两次相同的查询 ( SELECT ...hard_work...
) 并且它在我的应用程序中弄乱了事务。
目前它的工作方式如下:
DECLARE cursor FOR ...hardwork...;
WITH first_query AS (
SELECT ...hard_work... --second computation of hard_work
),
second_query AS (
SELECT ...another_query_using_hard_work...
)
SELECT *
FROM my_function('cursor'::refcursor) f(...) ;
最终我想有类似的东西(不工作)
WITH first_query AS (
SELECT ...hard_work...
),
second_query AS (
SELECT ...another_query_using_the_hard_work_query...
)
SELECT *
FROM my_function('first_query'::regclass) f(...) ;
当然 SELECT ...hard_work... 很昂贵(大约 50 毫秒),最好不要计算两次。应用是数据流,所以时间很宝贵,数据很重,所以在临时表中复制数据可能比计算两次(通常是几十MB)还要糟糕。
提出了其他解决方案
传输视图或表引用作为输入,这与使用游标的问题相同(即:计算的两倍,单独的语句)
传输/输出数组:使用 array_agg() 和 unnest() 强制进行大量计算
传输临时表:涉及复制数据:它可能比计算两次要长(我正在争取 50 毫秒)
传输物化视图:仅在 9.3 中可用
我将非常感激能对这个主题有深入的了解。
此致,
雷米-C
PS:psql-general邮件列表上的问题链接包含很多关于特定甚至所有代码的详细信息。
PPS:版本:postgres 9.2。操作系统:Ubuntu 12.04 LTE,客户端:PGAdmin3 用于测试,node.js 用于生产。