如何在PostgreSQL中使用3个函数调用加快查询速度

时间:2017-10-25 11:20:02

标签: sql postgresql

我有fucntion pb(IDCODE,0)运行IDCODE=320,并提供此示例数据:

select *
from pb(320,0)



logid entrydate qty
1       1.10.17   5
2       1.10.17   6
3       1.10.17   5
4       1.10.17   -3
5       2.10.17   6
6       3.10.17  -100

*它实际上提供了更多行(如20000),但我将其缩小为示例

pb是一个非常繁重的功能,但简单来说,它根据订单显示活动。

我想在entrydate的最后一行之后找到qty<0首次出现的qty>0

为了做到这一点,我需要做这样的事情:

Select Min(logid) where qty<0 and logid>(select max(logid) where qty>=0)

在上面的示例中,请求的结果为3.10.17 这是因为:

logid=5max(logid) where qty>=0

logid=6Min(logid) where qty<0 and logid>(select max(logid) where qty>=0)   实际上是:Select Min(logid) where qty<0 and logid>5

所以我写了以下查询:

select entrydate
from pb(320,0)
where logid= (     SELECT min(logid)
                    FROM pb(320,0)
                    where qty<0 and logid>(SELECT coalesce(max(logid),0)
                                           FROM pb(320,0)
                                           WHERE qty >= 0))

效果很好但是我称之为函数pb(320,0)是我的3倍。

这是非常耗时的,不用说我实际上在许多IDCODES(如214)上运行此查询,因此pb(IDCODE,0)实际运行214*3这太可怕了。

我该怎么办?

1 个答案:

答案 0 :(得分:2)

首先,使用CTE,因为Postgres可能会实现CTE。

但是,如果使用窗口函数,则只需要一个表引用:

with t as (
      select *
      from pb(320,0)
     )
select t.*
from (select t.*, max(case when qty > 0 then logid end) over () as last_poslogid
      from t
     ) t
where id > last_poslogid and qty < 0
order by id
fetch first 1 row only;

更新版本的Postgres支持filter子句,它比case更有效。