PostgreSQL视图中条件的自动重构

前端之家收集整理的这篇文章主要介绍了PostgreSQL视图中条件的自动重构前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个以下表格的表格:

[mytable]
id,min,max,funobj
-----------------------------------------
1      15       23      {some big object}
1      23       41      {another big object}
1      19       27      {next big object}

现在假设我有一个像这样创建的视图:

CREATE VIEW functionvalues AS
SELECT id,evaluate(funobj)
FROM mytable

其中evaluate是一个返回函数,用于评估大型funobj.视图的结果可能是这样的:

id,evaluate
--------------
1    15
1    16
1    ...
1    23
2    23
2    24
2    ...
2    41
...

我没有关于评估将返回的具体值的任何信息,但我知道它们总是介于mytable(包括边界)中给出的最小值和最大值之间

最后,我(或更好的是,第三方应用程序)对视图进行查询

SELECT * FROM functionvalues 
WHERE evaluate BETWEEN somevalue AND anothervalue

在这种情况下,Postgres会对mytable中的每一行评估函数evaluate,而根据where子句,如果函数的max和min不在给定值之间,则不必对其求值.由于评估是一个相当缓慢的功能,这给我带来了非常糟糕的表现.

更好的方法是使用直接查询

SELECT *
FROM (
    SELECT id,evaluate(funobj)
    FROM mytable
    WHERE
       max BETWEEN somevalue AND anothervalue
       OR min BETWEEN somevalue AND anothervalue
       OR (min < somevalue AND max > anothervalue)
) AS innerquery
WHERE evaluate BETWEEN somevalue AND anothervalue

有没有办法告诉postgres使用上面的查询(通过聪明的索引或类似的东西)而不改变第三方应用程序查询视图的方式?

P.S.:随意为这个问题建议一个更好的标题,我给的那个是……好吧……非特定的.

解决方法

Postgres无法将查询树中的限制推送到函数中;该函数始终必须扫描并返回整个基础表.并用同一张桌子重新加入.叹.
“分解”函数的主体并将其与查询的其余部分组合将需要类似宏的功能而不是函数.

更好的方法可能是不使用不受限制的set-returns函数,而是将函数重写为标量函数,只将一个数据行作为参数,并产生其值.

还有排序顺序的问题:外部查询不知道函数传递的顺序,因此需要显式的排序和合并步骤,除非是非常小的结果集(对于函数结果统计不可用,只有成本和估计的行数,IIRC.)

猜你在找的Postgre SQL相关文章