我正在尝试将一个表中的大量数据从PROD DB插入到Archive DB中的表。表具有相同的架构,存档表具有下垂的索引和“ Identity insert on”。我只需要插入Arh DB /表中不存在的记录。 我在SSIS序列程序包中使用“执行SQL任务”,它的运行速度非常慢(使用20000插入批处理大小)。我在10分钟内插入了20000条记录。仅提及我需要插入48000000条记录。 SQL Server是2016标准edt。 有解决方案吗?
SQL查询是:
SELECT TOP (@InsertBatchSize) s.ID,.....and other columns
FROM PRODDB.dbo.source_table AS s WITH (NOLOCK)
INNER JOIN ArchiveDB.dbo.MissingIDsTable AS t WITH (NOLOCK)
ON s.ID = t.ID
WHERE s.ID not in (SELECT ID
from ArchiveDB..destination_table
WHERE IsUpdated is null )
答案 0 :(得分:0)
任务-数据库之间的数据传输,目标数据库位于SQL 2016服务器上。
我建议采用以下方法:
通过以下步骤创建SSIS包:
使用(TABLOCK)选择插入...从
评论:
INSERT WITH (TABLOCK)
收缩用于利用SQL 2016的并行插入功能。答案 1 :(得分:0)
Execute SQL
不适合进行数据传输。它无法批处理数据,也无法对其进行转换。这就是数据流任务的工作。数据流任务允许使用流水线游标读取源数据,并使用批处理批量操作以最少的日志记录将它们写入数据目标。虽然它的速度取决于源查询。慢查询将导致执行缓慢。
这个问题缺少很多信息,例如源数据库和目标数据库中的表模式。我怀疑来自"Identity insert on"
的表的ID列是源中的IDENTITY和主键。如果您只关心新记录,则可以编写源查询,该源查询仅自上次执行以来读取数据,例如:
SELECT s.ID,.....and other columns
FROM PRODDB.dbo.source_table AS s
where ID>@maxId
@maxId
是提供给源查询的查询参数。无需批处理,SSIS可以根据数据源,批处理大小的目标设置等来执行此操作。
此查询仅应用于加载 new 数据。要创建初始副本,请使用源查询不过滤任何内容的其他数据流。使用Where ID>-1
之类的东西将返回所有数据,但仅在扫描整个索引之后才返回。当我们已经要复制所有数据时,为什么要那个呢?
该ID也应该是 target 表中的主键。这将加快加载参数值的select MAX(ID) from target
操作。它还将检测并防止不可避免的重复错误。无论我们多么谨慎,其他人总是会犯错误,从而导致数据重复。
您可以通过在插入之前禁用索引并在导入操作之后重新启用索引来提高导入性能。
那只是检测更改和复制数据的一种方法。另一种技术是在源表中启用Change Tracking并检索自上次作业运行以来修改的行。
您还可以将修改后的数据复制到登台表中,并将那个与目标一起插入INSERT / UPDATE更改。 ID或更改跟踪可用于查找修改后的数据。这样的好处是可以快速释放源代码。