微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

postgresql – postgres COALESCE懒惰吗?

如果我有这样的查询
SELECT COALESCE(
  (SELECT value FROM precomputed WHERE ...),alwaysComputeValue(...)
);

第二个表达式会被评估吗?
这还取决于执行计划员还是独立的?

从概念上讲它很懒惰:

Like a CASE expression,COALESCE only evaluates the arguments that are needed to determine the result; that is,arguments to the right of the first non-null argument are not evaluated.

https://www.postgresql.org/docs/9.6/static/functions-conditional.html

但是,如果右边的表达式不是volatile,那么它是否是懒惰的应该没有区别,所以在这种情况下,如果查询计划程序稳定或者是正常的,那么它将是允许的.不可变的,如果这似乎是一个明智的优化.

一个明显的例子是,使用SELECT COALESCE(a,b)FROM表,它可能会检索所有行的a和b字段,而不是检索a然后在必要时检索b.

关于在这里产生任何可观察效果的唯一方法是,如果你编写了一个易失性函数,并故意将其错误标记为稳定或不可变.然后,如果在左侧不为空的合并的右侧,则可以对其进行评估. (当然,一个功能确实很稳定,但如果它稳定,它就没有副作用,如果没有副作用,它是否发生是不可观察的).

鉴于:

CREATE OR REPLACE FUNCTION immutable_func(arg integer)
RETURNS integer
AS $BODY$
BEGIN
    RAISE NOTICE 'Immutable function called with %',arg;
    RETURN arg;
END;
$BODY$LANGUAGE plpgsql IMMUTABLE;

WITH data AS
(
    SELECT 10 AS num
    UNION ALL SELECT 5
    UNION ALL SELECT 20
)
select coalesce(num,immutable_func(2))
from data

规划器知道它对每行都有相同的immutable_func(2)结果,并为整个查询调用一次,给我们用2调用的消息Immutable函数.所以它确实已被评估,即使它不是在“第一个非空参数的权利的参数未被评估”的规则内.回报是在多个零数的(合理预期)情况下,它仍然只运行一次.

这是违反记录行为的信件是好的,因为我们已经告诉它这样的优化是有效的.如果这导致了问题,那么错误就是将功能标记为IMMUTABLE,而不是在急切的评估中.

它也可以是部分方式.使用SELECT COALESCE(a,Some_Func(b))FROM表,它不会急切地评估Some_Func(b),但它将检索b以便能够这样做.

任何时候它实际上影响(非作弊)可观察行为,遵循规则.

原文地址:https://www.jb51.cc/postgresql/191640.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐