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



我有这样的看法

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 和 foo2 相对昂贵,所以我只希望在用户明确要求时才评估它们。有什么方法可以实现这一点吗?

这种行为是有充分理由的。

Postgres中的每个函数都有一个波动性类别:VOLATILESTABLEIMMUTABLE。这些有两个目的:

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

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

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

(无论它们是否真的STABLE,您都可以这样做,但如果它们确实有副作用,则可能不符合您的最佳利益......

最新更新