使用记录ID列表作为输入在SQL Server中更新400万条记录

前端之家收集整理的这篇文章主要介绍了使用记录ID列表作为输入在SQL Server中更新400万条记录前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
在迁移项目期间,我面临着sql Server中400万条记录的更新.

更新非常简单;一个布尔字段需要设置为true / 1,我输入的是一个必须填充该字段的所有id的列表.(每行一个id)

当谈到这个大小的sql任务时,我并不是一个专家,所以我开始尝试1个UPDATE语句,其中包含“WHERE xxx IN({list of ids,以逗号分隔})”.首先,我尝试了一百万条记录.在测试服务器上的一个小数据集上,这就像一个魅力,但在生产环境中,这给出了一个错误.所以,我缩短了ID列表的长度几次,但无济于事.

我尝试的下一件事是将列表中的每个id转换为UPDATE语句(“UPDATE yyy SET booleanfield = 1 WHERE id ='{id}’”).某处,我读到每隔x行有一个GO是好的,所以我每100行插入一次GO(使用优秀的’sed’工具,从unix移植).

因此,我将400万个更新语句的列表分成每个250.000的部分,将它们保存为sql文件,并开始加载并运行第一个到sql Server Management Studio(2008).请注意我也尝试过sqlCMD.exe,但令我惊讶的是,这比sql Studio慢了大约10-20倍.

完成大约需要1.5小时,导致“查询已完成并出现错误”.但是,messages-list包含一个很好的列表“受影响的1行”和“0行受影响”,后者用于未找到id时.

接下来,我使用COUNT(*)检查了表中更新记录的数量,发现更新语句数量与更新记录数量之间存在数千条记录的差异.

然后我认为这可能是由于不存在的记录,但当我减去输出中“0行受影响”的数量时,有895条记录的神秘缺口.

我的问题:

>有没有办法找出“查询已完成但有错误”中的错误描述和原因.
>如何解释895条记录的神秘缺口?
>进行此更新的更好或最好的方法是什么? (因为我开始认为我正在做的事情可能非常低效和/或容易出错)

解决方法

解决此问题的最佳方法是将400万条记录插入表格中.实际上,您可以将它们放入带有标识列的表中,通过“批量插入”到视图中.
create table TheIds (rownum int identity(1,1),id int);

create view v_TheIds (select id from TheIds);

bulk insert into v_TheIds . . .

利用数据库中的所有数据,您现在可以拥有更多选项.尝试更新:

update t
    set booleanfield = 1
    where exists (select 1 from TheIds where TheIds.id = t.id)

您还应该在TheIds(id)上创建索引.

这是一个大型更新,全部作为一个事务执行.这可能会带来糟糕的性能影响并开始填充日志.您可以使用rownum列将其分解为较小的事务:

update t
    set booleanfield = 1
    where exists (select 1 from TheIds where TheIds.id = t.id and TheIds.rownum < 1000)

这里的exists子句相当于左外连接.主要区别在于此相关子查询语法应该在其他数据库中起作用,其中与更新的连接是特定于数据库的.

使用rownum列,您可以根据需要为更新选择任意数量的行.因此,如果整体更新太大,您可以将更新置于循环中:

where rownum < 100000
where rownum between 100000 and 199999
where rownum between 200000 and 299999

等等.您不必这样做,但如果您因某些原因要批量更新,则可以.

关键的想法是将id列表放入数据库中的表中,这样您就可以使用数据库的强大功能进行后续操作.

猜你在找的MsSQL相关文章