【发布时间】:2016-12-11 15:00:48
【问题描述】:
我们有一个正在迁移到新环境的生产数据库,在项目处于开发阶段时,客户要求对某些列和某些表中的数据进行匿名处理。
供应商提供了替换数据的脚本 - 例如:
UPDATE ThisTable SET Description = 'Anonymised ' + TableKey
现在的问题是有几个表有数百万行。最大的是 284,000,000 行。
当然,由于锁、TempDb 和行版本、日志文件等原因,上述语句永远不会适用于这样的表。
我有一个之前使用过的脚本,它本质上执行以下操作:
我目前的做法:
1.创建源表PK的临时表(并在PK上创建索引)。
2. 从临时表中选择前 n 个 PK 并处理源表中的相应行。
3. 从临时表中删除前 n 个 PK
4. 从第 2 步开始重复
这很好用——它提供了合理的性能(并且做了一些能够预测结束时间的指标)。但是,在大表上运行它会得到 4 天的预测运行时间!
我采取的其他措施是将数据库置于简单恢复模式。
我们拥有对服务器的独占访问权限,并且可以用它“做我们想做的事”。
核心问题是我们正在讨论大量行。一种想法是 BCP OUT 到文本文件,脱机处理,然后 BCP 输入。但是,我们仍在处理具有 284,000,000 行的文本文件!
问:
那么 - 关于如何实现上述目标的任何其他想法?我错过了一种“简单”的方法吗?
【问题讨论】:
-
您能否提供一些示例来说明您将如何匿名数据?
-
分批运行.....
-
如果您尝试一次全部更新,实际会发生什么?我不明白为什么拆分它会使其更快。我曾经使用基于主键的row_number,然后写出每万条记录的键,使用row_number % 10000 = 0找到,然后我可以一次删除10,000个键。
-
使用上面的简单 sql 一次全部更新会导致 TempDb 在尝试保存所有 RowVersions 时占用磁盘空间。也许增加 TempDb 大小和相关的磁盘空间会起作用。请记住,在查询运行大约 4.5 小时后更新失败。
-
所有我能想到的尝试是在进程之间拆分批次,例如将临时表中的范围标记为 a、b、c、d 等 - 然后进行一些并发处理 - 说,您可能已经认为它会遇到瓶颈,并且乐观地认为拥有 10 个进程会快 10 倍 - 在您编写和研究优化时 - 它可能已经完成
标签: sql-server tsql sql-server-2008-r2