首页 > 解决方案 > 根据条件更新多个列,哪种方法性能更好,或者是否有其他更好的方法

问题描述

drop table #source
create table #source
(
    userid int NULL,
    col1 nvarchar(max) NULL,
    col2 nvarchar(max) NULL,
    col3 nvarchar(max) NULL,
)
drop table #target
create table #target
(
    userid int NULL,
    col1 nvarchar(max) NULL,
    col2 nvarchar(max) NULL,
    col3 nvarchar(max) NULL,
    col4 nvarchar(max) NULL,
)
insert into #source values(1,'A','','B')
insert into #source values(2,'a',NULL,'b')

insert into #target values(1,NULL,'B','','extra')
insert into #target values(2,'aa',NULL,'b','extra')

select * from #source
select * from #target

update #target 
   set col1 = s.col1,
       col2 = s.col2,
       col3 = s.col3
   from #target t
   inner join #source s
     on s.userid = t.userid
where 
    s.col1 <> t.col1 or s.col1 is null and t.col1 is not null or s.col1 is not null and t.col1 is null
OR  s.col2 <> t.col2 or s.col2 is null and t.col2 is not null or s.col2 is not null and t.col2 is null
OR  s.col3 <> t.col3 or s.col3 is null and t.col3 is not null or s.col3 is not null and t.col3 is null


update #target 
   set 
       col1 = CASE WHEN s.col1 <> t.col1 or s.col1 is null and t.col1 is not null or s.col1 is not null and t.col1 is null THEN s.col1 ELSE t.col1 END,
       col2 = CASE WHEN s.col2 <> t.col2 or s.col2 is null and t.col2 is not null or s.col2 is not null and t.col2 is null THEN s.col2 ELSE t.col2 END,
       col3 = CASE WHEN s.col3 <> t.col3 or s.col3 is null and t.col3 is not null or s.col3 is not null and t.col3 is null THEN s.col3 ELSE t.col3 END
   from #target t
   inner join #source s
     on s.userid = t.userid

我只想在给定列的值不同并且还要考虑性能时才更新。非常感谢任何见解。提前致谢。在查看了许多线程之后,才知道如果值相同,SQL 内部不会执行更新。

标签: sql-serversql-updatequery-optimization

解决方案


  1. 确保两个表都在 user_id 上建立了(集群)索引。
  2. 如果只是为了可读性,请在所有这些AND和中添加一些括号。OR

你的第一个update将做你期望它做的事情:只更新有差异的记录。第二个update将更新所有(用户标识匹配)记录。

在性能方面,第一个对于系统来说可能会容易得多,因为实际记录数可能明显低于记录总数。

在极端情况下,您可能会争辩说,如果所有记录都需要更新,那么INNER JOIN第二个版本中更简单的版本在系统上可能会稍微容易一些,但在这种情况下,您可以摆脱CASE..WHEN..THEN构造,因为坦率地说,它并没有真正添加任何东西:当您将字段设置为一个值时,该值是否与以前的值相同都没有关系。


推荐阅读