如何防止调用冗余函数的postgres视图

时间:2018-05-17 01:18:16

标签: postgresql

我有这样的观点

create view v1 as select a,b,c,foo1(e,f) as f1, foo2(g,h) as f2 from t1;

当我做的时候

select a from v1;
正在调用foo1和foo2。这让我感到惊讶。 (其他引擎当然不会)。 Foo1 anf foo2相对昂贵,所以我只想让用户明确要求它们进行评估。有什么办法可以实现这个目标吗?

1 个答案:

答案 0 :(得分:1)

这种行为有充分的理由。

Postgres中的每个功能都有一个volatility categoryVOLATILESTABLEIMMUTABLE。这有两个目的:

  • 他们告诉查询优化器是否可以通过重新使用输出来省略函数调用。例如,它知道round()将始终为给定的参数返回相同的结果,而它不能对random()之类的内容做出此假设。
  • 他们告诉优化器是否安全省略了函数调用。如果该函数可能具有副作用(例如插入记录),则无法在不影响结果的情况下优化调用,因此为了确保可预测的行为,将始终评估此类函数。

无法自动推断波动率类别,因此Postgres默认为最安全的选项:函数为VOLATILE,除非另有声明,因此查询计划程序假定它们可能有副作用。即使这样的函数隐藏在视图中,并且查询忽略了它的结果,它仍然会被执行。

如果您将函数声明为STABLE,则只有在实际需要结果时才会运行它们。

(无论他们是否 STABLE,你都可以这样做,但如果他们确实有副作用,那么可能不符合你的最佳利益......)