这是一个简单的重现,它表明表达式 REPLACE (flname ,'(','') 将在 WHERE flname <> REPLACE (flname ,'(','') 的情况下被计算 两次,这是 CPU 密集型工作:
select col
into dbo.update_str
from
(
select top 1000 replicate ('a((', 2666) as col
from dbo.nums
union all
select top 1000 replicate ('a', 8000)
from sys.all_columns
)t
set statistics io, time on
update dbo.update_str set col = replace (col ,'(','')
--CPU time = 12278 ms, elapsed time = 12299 ms.
drop table dbo.update_str
select col
into dbo.update_str
from
(
select top 1000 replicate ('a((', 2666) as col
from dbo.nums
union all
select top 1000 replicate ('a', 8000)
from sys.all_columns
)t
update dbo.update_str set col = replace (col ,'(','') where
col <> replace (col ,'(','')
--CPU time = 23946 ms, elapsed time = 24007 ms.
在我的测试中,我填写表格dbo.update_str 2 次,因为如果它只填写一次,第二次更新无关。
在执行计划中发现第二种情况的双重工作:虽然两个计划在扫描后都有COMPUTE SCALAR(计算UPDATE的值),但第二种情况与predicate具有相同的表达式表扫描。
所以在我的测试用例中,其中一半数据有 '(',2000 行的时间差是 2 倍(当然我的行足够长,可以显示最坏的情况),第二次更新是 2时间变慢,因为行有很多字符要替换。