Sql server 根据性能更好的方法或是否有其他更好的方法,更新多列

Sql server 根据性能更好的方法或是否有其他更好的方法,更新多列,sql-server,sql-update,query-optimization,Sql Server,Sql Update,Query Optimization,我只想在给定列的值不相同并且考虑性能的情况下更新。非常感谢您的任何见解。提前谢谢。在查看了许多线程之后,我们了解到,如果值相同,SQL内部不会执行更新 确保这两个表都根据用户id进行了聚集索引。 如果只是为了可读性,请在所有这些和或之间添加一些括号。 您的第一次更新将执行您期望它执行的操作:仅更新存在差异的记录。第二次更新将更新用户ID记录上的所有匹配项 从性能角度看,第一种方法可能对系统来说要容易得多,因为实际记录数可能明显低于总记录数 在edge案例中,您可能会争辩说,如果所有记录都需要更新

我只想在给定列的值不相同并且考虑性能的情况下更新。非常感谢您的任何见解。提前谢谢。在查看了许多线程之后,我们了解到,如果值相同,SQL内部不会执行更新

确保这两个表都根据用户id进行了聚集索引。 如果只是为了可读性,请在所有这些和或之间添加一些括号。 您的第一次更新将执行您期望它执行的操作:仅更新存在差异的记录。第二次更新将更新用户ID记录上的所有匹配项

从性能角度看,第一种方法可能对系统来说要容易得多,因为实际记录数可能明显低于总记录数


在edge案例中,您可能会争辩说,如果所有记录都需要更新,那么来自第二个版本的更简单的内部连接在系统上可能会稍微容易一些,但在这种情况下,你可以摆脱这种情况..WHEN..THEN construction,因为坦率地说,它不会真正添加任何内容:当你将一个字段设置为一个值时,该值是否与以前的值相同根本不重要。

如果值相同,更新仍会导致更新;我还没有在最新版本中测试过它,但我确信更新不在乎值是否更改,它会将新版本写入磁盘。无论如何,找出最有效的方法就是简单地尝试一下。谢谢你花时间阅读我的帖子。行如果将列设置为当前的值,MySQL会注意到这一点,并且不会更新它。请看一看这个并分享你的想法。谢谢你在这上面花时间。问题没有提到这是MySQL。考虑到sql server标记,我假设它是MSSQL。我对MySQL几乎没有经验,很可能是说RDBMS的处理方式不同。有趣的我现在想知道这对受影响的行数有何影响。。。尽管如此,我仍然认为您可以摆脱这种情况..当..时..则直接赋值的构造将具有完全相同的效果。PS:链接文章还显示更新t1集合col1=col1+1,col2=col1;表现得相当离奇。。可怕但我们每天都在学习=总而言之,我最好的建议仍然是,唯一确定的解决方法是进行一些测试,确保您的卷具有“代表性”。在100行上效果很好的东西在10万行上可能会有很大的不同。再次感谢。我为混乱道歉。我不应该假设它可能是MSSQl中的相同实现。到目前为止,我在MSSQL文档中找不到任何内容。我试过用25万行11列。案例陈述耗时10秒,没有案例陈述耗时7秒。
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