如果我有这样的查询:
SELECT COALESCE(
(SELECT value FROM precomputed WHERE ...),
alwaysComputeValue(...)
);
第二个表达式会被评估吗? 这还取决于执行计划员还是独立的?
答案 0 :(得分:4)
与CASE表达式类似,COALESCE仅计算确定结果所需的参数;也就是说,不评估第一个非null参数右侧的参数。
答案 1 :(得分:4)
概念上它很懒惰:
与CASE表达式类似,COALESCE仅计算确定结果所需的参数;也就是说,不评估第一个非null参数右侧的参数。
https://www.postgresql.org/docs/9.6/static/functions-conditional.html
但是,如果右边的表达式不是易失性的,那么它是否是懒惰的应该没有区别,所以在这种情况下,查询计划者会急切地评估右手参数如果它是稳定的或不可改变的,如果这似乎是一个合理的优化。
一个明显的例子是SELECT COALESCE(a, b) FROM table
,它可能会检索所有行的a
和b
字段,而不是检索a
然后检索b
如果有必要的话。
关于在此获得任何可观察效果的唯一方法是,如果您编写了一个易失性函数并故意将其错误标记为stable
或immutable
。然后,如果在左侧不为空的coalesce
的右侧,则可能进行评估。 (当然,一个功能确实是稳定的,但如果它稳定,它将没有副作用,如果它没有副作用,是否发生它是不可观察的)。
假设:
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)
的结果都相同,并且整个查询只调用一次,给我们留言Immutable function called with 2
。所以它确实已被评估,即使它不在&#34规则内;第一个非null参数的权利的参数未被评估"。回报是在(合理预期)多个空num
的情况下,它仍然只运行一次。
这违反了记录行为的信件,这很好,因为我们已经告诉它这样的优化是有效的。如果这导致了问题,则错误将是标记为IMMUTABLE
的功能不在急切的评估中。
它也可以是部分方式。使用SELECT COALESCE(a, Some_Func(b)) FROM table
时,它不会急切地评估Some_Func(b)
,但它会检索b
以便能够这样做。
任何时候它实际上影响(非作弊)可观察行为,遵循规则。