在 PostgreSQL 中重用存储过程的结果
Posted
技术标签:
【中文标题】在 PostgreSQL 中重用存储过程的结果【英文标题】:Reuse of stored procedure results in PostgreSQL 【发布时间】:2016-10-13 20:48:00 【问题描述】:我正在研究 PostgreSQL 数据库的只读副本,不可能创建任何临时表(只读事务)。
考虑我有存储过程foo(...)
它返回我TABLE(...)
结果(或SETOF Foo_Type
相同)。
这个Foo_Type
有一些type
字段,用于定义行中的数据类型。
在另一个具有固定返回类型的过程foo_wrapper(...)
(它也是TABLE(...)
或者说SETOF Foo_Wrapper_Type
)中,我需要执行以下操作:
取决于Foo_Type.type
的值,我需要使用left join
将来自foo(...)
的结果与不同的表合并。目前是这样处理的:
...
return query
select
ft.*,
a1.x1
from foo(param1, param2, ...) ft
left join a_table a on ...
where ft.type = 'value_1'
union
select
ft.*,
b1.x1
from foo(param1, param2, ...) ft
left join b_table b on ...
where ft.type = 'value_2'
...
union
-s 有几十个。
不要告诉我我的 Schema 设计得多么邪恶和糟糕。我知道,它是遗留模式。
我要问的是如何避免在此语句中多次调用foo(...)
过程?
这个foo_wrapper(...)
程序运行非常缓慢。我怀疑这是因为多次调用具有相同参数的foo(...)
过程,我不确定数据库是否将其结果缓存在一个会话中。
所以我的问题由两部分组成:
在我的大联合选择之前,有什么方法可以“提取”并保存 foo(...)
的结果?
DECLARE results SETOF Foo_Type
不起作用。
这可能不是优化的重点,有人肯定会声称foo(...)
的第一次调用的结果被缓存以供此过程中的进一步调用?
【问题讨论】:
【参考方案1】:使用公用表表达式:
return query
with foo_data as (
select *
from foo(param1, param2, ...)
)
select ft.*,
a1.x1
from foo_data ft
left join a_table a on ...
where ft.type = 'value_1'
union
select ft.*,
b1.x1
from foo_data ft
left join b_table b on ...
where ft.type = 'value_2'
...
您可能想使用union all
而不是union
。
【讨论】:
哇,看起来像是一个决定。我明天会检查它,我的投票和检查不会延迟!谢谢!以上是关于在 PostgreSQL 中重用存储过程的结果的主要内容,如果未能解决你的问题,请参考以下文章
Informix SQL / 在另一个查询中重用存储过程的结果