我有一个数据库,在其中我将文件加载到临时表中,从该临时表中我有1-2个连接来解析一些外键,然后将这些行插入到最终表中(每月有一个分区)。我有大约34亿行用于三个月的数据。
使这些行暂存到最终表中的最快方法是什么?SSIS数据流任务(使用视图作为源并激活快速加载)或插入INTO SELECT ....命令?我尝试了“数据流任务”,并在5个小时内可以得到大约10亿行(8核/服务器上192 GB RAM),这对我来说感觉很慢。
我有一个数据库,在其中我将文件加载到临时表中,从该临时表中我有1-2个连接来解析一些外键,然后将这些行插入到最终表中(每月有一个分区)。我有大约34亿行用于三个月的数据。
使这些行暂存到最终表中的最快方法是什么?SSIS数据流任务(使用视图作为源并激活快速加载)或插入INTO SELECT ....命令?我尝试了“数据流任务”,并在5个小时内可以得到大约10亿行(8核/服务器上192 GB RAM),这对我来说感觉很慢。
Answers:
一种常用方法:
INSERT dbo.[Target] WITH (TABLOCKX) SELECT ...
n
,这可以减轻事务日志的压力,当然,这意味着如果某个批处理失败,则只需从该批处理开始即可。我在此发布了有关此内容的博客(引用删除时,也应用了相同的基本概念):http : //www.sqlperformance.com/2013/03/io-subsystem/chunk-deletes 如果您的分区是物理分区,而不仅仅是逻辑分区,那么可以通过让不同的进程同时填充不同的分区来获得一些时间(当然这意味着您不能使用TABLOCK
/ TABLOCKX
)。这假定源也适合于多个进程的选择,而无需选择重叠/锁定等,并使操作的这一端更加缓慢(提示:在源上创建适合于目标分区方案的聚簇索引)。
您还可以考虑一些更原始的东西,例如BCP OUT
/BCP IN
。
我不知道我会跳到SSIS来解决这个问题。那里可能有一些效率,但我不知道这种努力可以证明节省了费用。
从SSIS的角度看您的问题,我觉得这样做可能花了很长时间的原因是您没有进行批处理。这可能会导致SSIS管道中填充过多行,从而可能会阻碍SSIS性能。您需要做的是更改每批设置的行数,并可能更改最大插入提交大小。现在,您也对此进行了设置将取决于SSIS服务器可用的内存量?您的SQL Server实例的磁盘速度是多少?最好的方法是测试。例如使用10,000。这将一次向服务器10,000发送一批,从而防止您的管道溢出,并有助于更快地运行此过程。这些设置在您的OLEDB目标中设置。
如果存在问题,您还可以按照@AaronBertrand的建议在操作前后添加执行SQL任务,并删除/重新向表添加任何索引或约束。