【问题标题】:Update all or only where oldvalue<>newvalue?更新全部或仅更新旧值<>新值?
【发布时间】:2018-01-12 08:46:12
【问题描述】:

我使用的是 SQL Server 2014。

哪个会跑得更快,为什么,有没有办法使用分析器找出:

update tablename set flname=replace(flname,'(','')

update tablename set flname=replace(flname,'(','') where flname<>replace(flname,'(','')

flname 字段上没有索引。我可以创建一个。我希望 where 会过滤掉大约 90% 的行。

【问题讨论】:

  • 保留 WHERE 子句!将使交易规模更小。 where flname like '%(%'.
  • 使用 set statistics time on 并运行你的马;)
  • 较小的交易也意味着较小的交易冲突风险!

标签: sql sql-server tsql sql-update


【解决方案1】:

这是一个简单的重现,它表明表达式 REPLACE (flname ,'(','') 将在 WHERE flname &lt;&gt; 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时间变慢,因为行有很多字符要替换。

【讨论】:

    【解决方案2】:

    在我的测试中没关系。

    你可以如下测试:

    SELECT TOP 10000 flname INTO #TEST FROM tablename 
    
    SET STATISTICS IO,  TIME ON
    UPDATE #TEST SET flname = REPLACE (flname ,'(','')
    
    UPDATE #TEST SET flname = REPLACE (flname ,'(','') WHERE 
    flname <> REPLACE (flname ,'(','')
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多