在 PostgreSQL 中重用存储过程结果

Reuse of stored procedure results in PostgreSQL

我正在处理 PostgreSQL 数据库的只读副本,不可能创建任何临时表(只读事务)。

假设我有存储过程 foo(...),return 是我的 TABLE(...) 结果(或者 SETOF Foo_Type 是相同的)。

这个 Foo_Type 有一些 type 字段定义行中的数据类型。

在另一个程序 foo_wrapper(...) 中固定 return 类型(它也是 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(...) 过程,我不确定数据库是否将其结果缓存在一个会话中。

所以我的问题由两部分组成:

  1. 有什么方法可以 "extract" 并在我的大联合 select 之前保存 foo(...) 的结果? DECLARE results SETOF Foo_Type 无效。

  2. 可能这不是优化的重点,有人肯定会声称 foo(...) 的第一次调用的结果被缓存以供在此过程中进一步调用?

使用常见的 table 表达式:

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