如果我有这样的查询:postgres COALESCE是否懒惰?
SELECT COALESCE(
(SELECT value FROM precomputed WHERE ...),
alwaysComputeValue(...)
);
将在第二公式进行计算? 这也取决于执行计划者或它是独立的吗?
如果我有这样的查询:postgres COALESCE是否懒惰?
SELECT COALESCE(
(SELECT value FROM precomputed WHERE ...),
alwaysComputeValue(...)
);
将在第二公式进行计算? 这也取决于执行计划者或它是独立的吗?
它是懒:
等的情况下表达,COALESCE只判断所需要来确定结果的参数;也就是说,不评估第一个非空参数右边的参数。
https://www.postgresql.org/docs/9.6/static/functions-conditional.html
但是,如果表达的权利是不挥发的话,应该没有什么区别它是否是懒还是没有,所以在这种情况下,这将是允许的查询规划热切如果它是稳定的或不可变的,则评估右边的论点,如果这看起来是一个明智的优化。
一个明显的例子是,与SELECT COALESCE(a, b) FROM table
它可能会检索所有行的a
和b
字段,而不是获取a
,然后在必要时检索b
。
关于在这里产生任何可观察效果的唯一方法是,如果您编写了易失性函数并故意将其错误标记为stable
或immutable
。那么它将是可能的它将被评估,如果在右边的3210左手不为空。 (对于一个确实稳定的函数,当然也是可能的,但是如果它是稳定的,那么它就没有副作用,如果没有副作用,它是否会发生也不会被观察到)。
考虑:
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
。所以它的确已经过评估,即使它不在“第一个非空参数的权利参数未被评估”的规则之内。这个回报就是在多个无效的(合理预期)情况下,它仍然只能运行一次。
这是违反记录的行为的信是好的,因为我们已经告诉它,这样的优化是有效的。如果这导致了问题,该错误将会使标记为IMMUTABLE
的功能不在急切的评估中。
它也可以是部分路径。与SELECT COALESCE(a, Some_Func(b)) FROM table
它不会热切地评估Some_Func(b)
,但它将检索b
能够这样做。
任何时候它实际上会影响(非作弊)的可观察行为,遵循该规则。
哇,这么长时间的答案,但是..我知道它可以评估*在理论上*如果我标记函数不变或稳定,并设置它为规划师低成本,*但*这*真的*发生? :-) – langpavel
是的,它可以。将更新答案。 –
等的情况下表达,COALESCE只判断所需要来确定结果的参数;也就是说,不评估第一个非空参数右边的参数。
好问题。我会说:检查计划。 – wildplasser