在SSIS中防止“INSERT IF NOT NOT EXISTS”中的死锁

时间:2013-11-05 16:57:10

标签: sql-server ssis sql-server-2012

我正在尝试将数据插入数据库,但首先我使用查找检查每一行是否存在,类似于此处建议的方法: How to prevent SSIS from importing data from a file that already exist in database?

SELECT DISTINCT VALUES    // OleDb Source
         |
       LOOKUP             // If exists
         |                // No Match Output
  OLE DB DESTINATION      // Insert new records

我正在使用RetainSameConnection=True在我的工作流程上启用交易。使用大约10,000行的默认缓冲区,当行传递到OLE DB目标时,目标INSERT将使用查找SELECT锁定。

我已经尝试了SET READ_COMMITTED_SNAPSHOT ON,这会起作用,但是在查找期间的性能现在非常慢,我认为这是由于RetainSameConnection属性,我无法判断SSIS是否使用了READ承诺的SNAPSHOT隔离级别。我想忽略目标上的失败,但我读到它会导致批量插入完全失败而不是按行失败。我还考虑在所有读取中使用NOLOCK,但它会将我的所有查找转换为SQL查询。

源DB可能会读取数百万行。 有没有更好的方法来实现这一目标?

2 个答案:

答案 0 :(得分:0)

我记得他们将所有插入行写入原始文件。然后有第二个数据流(在第一个数据流完成之后)将原始文件记录插入到目标表中。

答案 1 :(得分:0)

这个问题进入的领域的答案将更多地基于偏好和经验,而不仅仅是一种容易定义的方式。可能会有很多答案会显示出可能对您有用的不同方法,但其中任何一个的基础知识都将基于几个方面

  1. 在预缓存数据流任务期间减少查找中保存的行数

    一般来说,在数据流开始执行之前填充所有查找的值,并根据查找的配置从源读取数据。如果您以这种方式配置了SSIS,那么无论隔离级别如何,查找和在表中插入行之间都不应存在任何争用。

    根据你上面所说的,我认为,由于你的配置,查找的性能可能没有大幅改变,但更多的是因为每次执行时缓存到查询中的数据量都在增加。

  2. 更改查找模式以使用其他模式

    对于大多数情况,查找的最基本实现通常都很好。但是,如果性能是包执行的一个重要问题,那么可能有其他更理想的方法来实现相同的目标。我在博客中谈到的其中一个是指使用合并连接作为标准查找的替代方法。这可能不适合您的情况,因为我设计了这个特定的策略来涵盖涉及大型数据集的角落案例,但希望它应该给你一些想法。

    我在下面的链接中详细介绍了该模式

    https://web.archive.org/web/20140819083150/http://bigdatabigdave.info/archive/2013/02/15/alternate-ssis-lookup-pattern-merge-join/