根据条件更新多个列,哪种方法性能更好,或者是不是有其他更好的方法
Posted
技术标签:
【中文标题】根据条件更新多个列,哪种方法性能更好,或者是不是有其他更好的方法【英文标题】:Update multiple columns based on condition which approach is better in performance or is there any other better approach根据条件更新多个列,哪种方法性能更好,或者是否有其他更好的方法 【发布时间】:2020-10-08 09:43:36 【问题描述】: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内部不会执行更新。
【问题讨论】:
如果值相同,update
仍会导致更新;尚未在最新版本中对其进行测试,但我非常确信更新不关心值是否更改,无论如何它都会将新版本写入磁盘。无论如何,找出最有效的方法的最简单方法就是尝试一下。
【参考方案1】:
-
确保两个表都在 user_id 上(集群)索引。
为所有
AND
和 OR
添加一些括号,如果只是为了便于阅读。
您的第一个update
将按照您的预期进行:仅更新有差异的记录。第二个update
将更新所有(匹配用户ID)记录。
在性能方面,第一个对于系统来说可能会容易得多,因为实际记录数可能远低于记录总数。
在极端情况下,您可能会争辩说 IF 所有记录都需要更新,那么第二个版本中更简单的INNER JOIN
在系统上可能会稍微容易一些,但在这种情况下,您可以获得摆脱 CASE..WHEN..THEN
构造,因为坦率地说,它并没有真正添加任何东西:当您将字段设置为一个值时,该值是否与以前的值相同并不重要。
【讨论】:
感谢您花时间阅读我的帖子。 dev.mysql.com/doc/refman/8.0/en/update.html line “如果您将列设置为它当前具有的值,MySQL 会注意到这一点并且不会更新它。”请看看这个并分享你的想法。感谢您在这方面的时间。 啊。问题没有提到这是 MySQL。给定 sql-server 标签,我认为它是 MSSQL。我几乎没有使用 MySQL 的经验,很可能是说 RDBMS 以不同的方式处理这个问题。有趣的。我现在想知道这如何/是否会影响受影响的行数...不过,我仍然认为您可以摆脱CASE..WHEN..THEN
构造,因为直接分配新值将具有完全相同的效果。 (PS:链接的文章还显示UPDATE t1 SET col1 = col1 + 1, col2 = col1;
的行为相当奇特。可怕但我们每天都在学习=)
总而言之,我最好的建议仍然是,解决这个问题的唯一可靠方法是进行一些测试,只需确保您的卷具有“代表性”。在 100 行上效果很好的方法在 100k 行上效果可能会大不相同。
再次感谢。我为混乱道歉。我不应该假设它可能是 MSSQl 中的相同实现。到目前为止,我在 MSSQL 文档中找不到任何内容。我尝试了 250k 行和 11 列。 case 语句耗时 10 秒,没有 case 语句则耗时 7 秒。以上是关于根据条件更新多个列,哪种方法性能更好,或者是不是有其他更好的方法的主要内容,如果未能解决你的问题,请参考以下文章