是否有任何解决方案比简单的INSERT INTO
或导出和导入文件更有效地将具有3列的表中的数百万行移动到另一个数据库中的类似表,而不阻塞目标数据库,并且不会丢失在发生故障时可以回滚的事务中的任何记录?
发布于 2017-09-20 11:50:11
是否有比简单插入或导出和导入文件更有效的解决方案将数百万行从具有3列的表移动到另一个数据库中的类似表中,
你最好的选择就是SSIS。
而不阻塞目标数据库
插入到一个表中不会阻塞数据库,但它会在某种程度上导致对表的阻塞。阻塞的长度和严重程度将在很大程度上取决于索引的数量以及它们是否适合您的查询。
如果要减少阻塞,请将数据插入较小的块。为了避免锁升级锁升级,我通常一次去1000行左右。
另一种减少阻塞的方法是在读取数据的查询中使用乐观隔离度。
以及在发生故障时可以回滚的事务中没有丢失任何记录?
这也是为什么小批是个好主意的另一个原因。它将使您更容易找出违规行,重试事务,等等。
在这篇文章中也有一些巧妙的技巧,由Michael:在线修改表。第1部分:迁移策略撰写。
发布于 2017-09-20 10:34:20
对于较大的数据集,通常推荐使用涓流提要(增量),但它将取决于您希望运行它的频率和实际的增量卷。
如果您只是希望保持次要副本与主副本保持一致的状态/同步,则可能应该查看复制、日志传送或可用性组。
您还可以使用BCP或SSIS将数据移动到新数据库中--这不会锁定实际的目标表--然后使用分区切换,这将导致目标数据库中的最小锁定。
Kendra有一篇很好的关于分区切换的文章:https://littlekendra.com/2017/01/19/why-you-should-switch-in-staging-tables-instead-of-renaming/
发布于 2017-09-21 21:21:48
在我的工作中,我们用一个专门开发的C#应用程序做了一个小技巧,每天从我们的Oracle服务器将大约500-600gb的数据移动到我们的,在大约一个小时内,使用大量线程(大约30个线程).逻辑可以在没有太多问题的情况下转移到SSIS (这是因为我们首先在SSIS包xD上测试了性能)
我们打开到源表的N个连接,并修改了select,以便根据数字字段的模块( Oracle中的MOD,SQL Server中的%)筛选行.这个技巧使我们能够同时读取多个线程的单个表(这类似于使用Sqoop将数据导入Hadoop时发生的情况,因为Sqoop使用索引数字字段,并在分配给作业的N个工作人员上拆分读取任务,每个工作人员同时读取不同范围的数据)
例如,您可以简单地连接到同一个表,并将这种查询放到数据流任务中读取数据。
select number_field, varchar_field, date_field from table where (number_field % 10) = 0
select number_field, varchar_field, date_field from table where (number_field % 10) = 1
....
select number_field, varchar_field, date_field from table where (number_field % 10) = 8
select number_field, varchar_field, date_field from table where (number_field % 10) = 9
每个查询将从源表读取不同的数据块,并在目标表上插入,如果使用OLEDB目标,您可以编辑选项以取消选中锁定目标表的选项,并使用低于5000行的批处理大小,因为在5000行以上,行首先在temp db上写入,然后传输到目标表,正如Erik说的,1000行不是一个糟糕的批处理大小。
使用这个技巧,我们将每天10行的表移动到大约5亿行(历史数据.它每天通过OLTP Oracle上运行的一些进程进行更新.我们每天截断目标表并再次读取Oracle中的所有行.这就是为什么我们的过程到达执行的时间)
https://dba.stackexchange.com/questions/186405
复制相似问题