eid*_*lon 8 sql-server isnull lazy-evaluation short-circuiting
TI ISNULL()是一个懒惰的功能?
也就是说,如果我编写如下代码:
SELECT ISNULL(MYFIELD, getMyFunction()) FROM MYTABLE
它会一直评估getMyFunction()还是只会在MYFIELD实际为空的情况下评估它?
这工作正常
declare @X int
set @X = 1
select isnull(@X, 1/0)
Run Code Online (Sandbox Code Playgroud)
但是引入聚合会使其失败并证明有时可以在第一个参数之前评估第二个参数。
declare @X int
set @X = 1
select isnull(@X, min(1/0))
Run Code Online (Sandbox Code Playgroud)
它认为最有效的就是它。
现在它在功能上是懒惰的,这是重要的事情。例如,如果col1是一个,当为空varchar时,它总是包含一个数字col2,那么
isnull(col2, cast(col1 as int))
Run Code Online (Sandbox Code Playgroud)
将工作。
但是,没有指定它是在空检查之前还是与空检查同时尝试强制转换并在col2不为空时吃掉错误,或者是否仅在col2为空时才尝试强制转换。
至少,我们希望它col1在任何情况下都能获得,因为对表进行一次扫描获取 2 个值将比两次扫描各获取一个值更快。
相同的 SQL 命令可以以非常不同的方式执行,因为我们给出的指令会根据表的索引和统计信息转换为较低级别的操作。
因此,就性能而言,答案是“当它看起来是一个好主意时,它就是一个好主意,否则它就不是”。
从观察到的行为来看,它是懒惰的。
编辑:米凯尔·埃里克森(Mikael Eriksson)的回答表明,在某些情况下,由于不懒惰,确实可能会出错。我将在性能影响方面坚持我的答案,但就至少在某些情况下的正确性影响而言,他的答案至关重要。