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.) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |