表达式求值规则
子表达式的求值顺序是不确定的。运算符或函数的各个输入参数不一定按从左到右或任何固定顺序进行求值。
如果表达式的结果可以仅通过部分子表达式计算得出,那么其他子表达式可能根本不会被执行。例如,下面的表达式中:
SELECT true OR somefunc();
somefunc()
很可能不会被调用。同样,在下面的表达式中:
SELECT somefunc() OR true;
结果也是如此。
这与某些编程语言中布尔运算符强制的从左到 右求值顺序不同。
不要在复杂表达式中使用带副作用的函数,尤其是在 WHERE
和 HAVING
子句中,因为这些子句在生成执行计划时会被多次重写和重新评估。布尔表达式(AND
/ OR
/ NOT
组合)在这些位置可以根据布尔代数规则被任意重排。
如需强制求值顺序,可以使用 CASE
表达式。下面这个例子试图通过逻辑短路避免除以零,但并不可靠:
SELECT ... WHERE x <> 0 AND y/x > 1.5;
以下写法才是可以确保顺序执行的方式:
SELECT ... WHERE CASE WHEN x <> 0 THEN y/x > 1.5 ELSE false
END;
这种写法中的 CASE
表达式会阻止优化器进行某些优化,因此仅在确有必要时使用。