重用存储过程会导致PostgreSQL

时间:2016-10-13 20:48:01

标签: sql postgresql stored-procedures plpgsql query-performance

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

考虑我有存储过程declare @dt datetime = '2015-06-04 09:54:15' select replace(format(@dt, 'MMM dd yyyy hh:mmtt'), ' 0', ' ') set @dt = '2015-12-31 19:54:15' select replace(format(@dt, 'MMM dd yyyy hh:mmtt'), ' 0', ' ') set @dt = '2015-12-31 00:00:00' select replace(format(@dt, 'MMM dd yyyy hh:mmtt'), ' 0', ' ') ,它会返回foo(...)结果(或TABLE(...)相同的结果)。

SETOF Foo_Type有一个Foo_Type字段,用于定义行中的数据类型。

在另一个具有固定返回类型的type过程中(它也是foo_wrapper(...)或者说TABLE(...))我需要执行以下操作:

取决于SETOF Foo_Wrapper_Type值,我需要使用Foo_Type.typefoo(...)的结果与不同的表合并。这就是目前的工作方式:

left join

这里有几十个... 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' ... - s。

不要告诉我设计我的架构是多么邪恶和可怕。我知道,它是遗留架构。

我在询问的是如何避免在此声明中多次调用union程序?

foo(...)程序运行速度极慢。我怀疑这是因为foo_wrapper(...)过程多次调用相同的参数,我不确定DB在一个会话中缓存其结果。

所以我的问题包括两部分:

  1. 在我的大联盟选择之前,有没有办法“提取”并保存foo(...)的结果? foo(...)不起作用。

  2. 可能不是优化的重点,有人可以肯定地声称DECLARE results SETOF Foo_Type的第一次调用结果会被缓存,以便在此程序中进一步调用吗?

1 个答案:

答案 0 :(得分:2)

使用公用表表达式:

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