我正在尝试使用 SSIS 插入以下查询。我这样做只是因为目标表中已经存在一些重叠的 ID。我尝试使用以下方法获取两个表的最小和最大 ID,以便仅插入不存在的行:
/*
--SourceTable
MinID MaxID
select 552596452-633166940
--destination table
MinID MaxID
450485204 596693972
*/
然后我现在用它来实现使用 SSIS 包的插入。我无法让这个包运行。有什么我做错了吗?是否有任何其他 SSIS 数据流可用于解决此问题?我选择使用 SSIS 是因为记录大约有 3000 万行,在 SQL 上运行需要很长时间,而且它也会很快填满日志空间,这会影响服务器的性能。
INSERT INTO dbo.destinationtable
([id]
,[userId]
,[serviceId]
,[keyId]
,[wappush]
,[builturl]
,[datestamp]
,[pocessingTime]
,[UserAgent]
,[Referer]
,[fallBack]
,[Error]
,[ClientIP]
,[AdvertUrl])
SELECT id, userId, serviceId, keyId, wappush, builturl, datestamp, pocessingTime,
UserAgent, Referer, fallBack, Error, ClientIP, AdvertUrl
FROM sourcetable a (nolock)
WHERE (datestamp < DATEADD(d, 0, DATEDIFF(d, 0, GETDATE() - 60)))
AND id > 596693972 and id <= 633166940
ORDER BY id
如果你打算使用 SSIS,我可以建议你使用它吗?;)
我相信您正在尝试做的是插入一些目标中尚不存在的数据。您已经使用最小/最大逻辑确定了需要哪些数据,并尝试对目标执行类似的操作。
对于初学者来说,这
OLE DB Command
是你应该谨慎使用的东西。它执行单例操作,因此您希望这个东西处理的行数应该是几十,也许是几百。绝对不是8000万。您的数据流应该是这样的
我有一个 OLE DB 源(可以使用 ADO.NET,但如果您需要参数化查询,它会稍微复杂一些)。您可以使用现有的查询,或者如果您需要将其分块,因为您有活动的系统,就这样吧。
查找组件
LKP RM_DimEmplo...
是此操作的关键。当包启动时,它将在该组件中运行源查询并缓存所有值。这听起来很贵,所以不要让它成为现实。不要只选择dbo.destinationTable
. 编写查询以仅返回进行匹配所需的键。应该是那些ID。那将非常狭窄,不应该那么糟糕。这里的想法是您将拥有源行,并根据这些键将它们与目标表的缓存进行比较。由于您不担心检测差异,因此您知道任何不匹配的内容都需要删除,因此在“常规”选项卡上,将“指定如何处理没有匹配条目的行”更改为使用Redirect rows to no match output.
否则,当它不匹配时,它会爆炸。如果您发现它仍然对您的系统有影响,那么您需要采用更高级的方法,即在查找组件上使用表达式来过滤数据范围以匹配传入的 ID。因此,您已确定源范围为 100到 200。没有必要在目标中提取完整的 0 到 1000 范围的键,您只需让查找缓存在操作范围内的键。除非您的机器上没有可用的 RAM,否则 80M 应该不会太重。
执行
OLE DB Command
单例、一次性操作。OLE DB Destination
可以执行单例插入(默认为 2005 - )Table or view
或基于集合/批处理的更新(Table or View - fast load
),这可以快速尖叫猎豹车轮。由于您正在加载大量数据,除非您希望您的管理员讨厌您,否则将 Max insert commit size 更改为默认值 2147483647 以外的其他值。这基本上是说在全部插入之前不要提交任何内容。这可能会导致您的事务日志匆忙变大。你的问题的好处是你可以随心所欲地运行它。假设 1M 行被加载并且发生了一些不好的事情。只需重新启动。不管提交了多少,当它重新启动时,它可能会提取相同的源数据,但您的查找将具有来自目标的最新键集,因此结果将不会对这些键执行任何操作。我知道,你会认为每个人都喜欢他们的目标系统中的重复项,但出于某种原因,这在某些地方并不适用......
包起来
我不能足够推荐集成服务系列的阶梯。专门针对这个问题,Level 3