【发布时间】:2011-04-11 18:56:23
【问题描述】:
我们有许多数据库,在其中一个表中存储了 10 到 100 GB 的数据。它包含图像数据。问题是这些数据库中有很多是不正确地创建的。基本上主键实际上并不是主键。是使用可空列上的唯一索引创建的。其中一些具有 int 作为主键,而不是 bigint。
所以我们一直在慢慢地检查和修复这些数据库。它们在 SQL Server 2000 到 SQL Server 2008 上运行,尽管大多数有主键问题的都在 SQL Server 2000 上。问题是,我们不想在转换表时将数据库锁定一整天。我们采用了几种策略:
告诉 SQL Server 直接更改列类型。这会锁定表直到它完成,并且在许多情况下将它放置一夜之后,它仍然没有完成。
一次性将所有图像插入到新表中。这更容易被中断,但整个表基本上都被写入了进程中的日志文件。
-
在目标表中不存在行时插入 100 行。好处是他们可以在此过程中继续使用数据库(性能受到很大影响),并且可以在任何时候任意停止和重新启动它,并且它可以防止 100GB 以上的日志文件。这就是我们目前正在做的事情,但是随着目标表变得越来越大,查找不存在的前 100 行会变得非常慢。 UPDATE STATISTICS 和 DBCC INDEXDEFRAG 有很大帮助,但在最近的尝试中,我们达到了一个点,甚至一次有 100 张图像坐在那里没有响应。
INSERT INTO %s SELECT TOP 100 Source.* FROM %s AS Source WITH (NOLOCK) LEFT OUTER JOIN %s AS Target WITH (NOLOCK) ON Source.DocumentID = Target.DocumentID WHERE Target.DocumentID IS NULL ORDER BY Source.DocumentID
所以问题是,有没有一种可以高效且可恢复的方式复制批量数据的选项?它不一定要 100% 准确,只要它完成了 99% 的工作,我们总是可以在最后返回并修复任何差异。
【问题讨论】:
标签: sql-server-2000 bulkinsert