【问题标题】:Reuse of stored procedure results in PostgreSQL在 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(...) 过程,我不确定数据库是否将其结果缓存在一个会话中。

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

  1. 在我的大联合选择之前,有什么方法可以“提取”并保存 foo(...) 的结果? DECLARE results SETOF Foo_Type 不起作用。

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

【问题讨论】:

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


    【解决方案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

    【讨论】:

    • 哇,看起来像是一个决定。我明天会检查它,我的投票和检查不会延迟!谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-23
    • 1970-01-01
    • 1970-01-01
    • 2020-02-18
    • 1970-01-01
    相关资源
    最近更新 更多