【问题标题】:Preventing Duplicate Table Inserts防止重复的表格插入
【发布时间】:2013-02-01 09:27:12
【问题描述】:

数据库是 SQL Server 2008。我有一个查询,它从一个或多个表中提取行,然后尝试将它们插入到表变量中。

我想要一种防止重复插入的有效方法,所以我想出的是:

INSERT INTO @MyTableVariable
SELECT SomeID
FROM SomeTable st
INNER JOIN SomeOtherTable sot ON sot.SomeID = st.SomeID
LEFT JOIN @MyTableVariable t ON t.SomeID = sot.SomeID
WHERE t.SomeID IS NULL

然而,这似乎并不能防止在某些情况下重复插入。

似乎(如果您考虑一下并查看查询计划,这是有道理的)在左连接操作中只使用了@MyTableVariable 的初始“状态”。换句话说,如果在运行此语句之前@MyTableVariable 中已经包含 SomeID,这将防止重复,但如果 SomeTable/SomeOtherTalbe 上的 FROM/INNER JOIN 导致 SomeID 重复,则不会防止重复。

除了简单地在 SELECT 语句上添加一个 DISTINCT 之外,还有其他更有效的方法来处理这个问题吗?

【问题讨论】:

  • 如果您不想使用DISTINCTGROUP BY,那么您可以在列上创建唯一索引,并忽略重复键。
  • 您如何处理重复的键错误?这实际上比执行 distinct 更快吗?

标签: sql-server-2008 tsql insert duplicate-removal


【解决方案1】:

据我所知,在 SQL Server 中没有INSERT IGNOREINSERT ON DUPLICATE KEY 的方法。当然, MERGE,但它不会解决您的问题,因为它的行为与您的 INSERT 相同,即它会引发异常。

还有其他更有效的方法来处理这个问题吗?

在我看来,您的选择是:

  1. 尝试寻找更具体的过滤/加入方式,以免产生重复。

  2. 'Slap' DISTINCT 在较早阶段的某处,以防止重复进入首先连接的任何一个表。

  3. 将主要负责产生重复的表转换为在本地应用 DISTINCT 的子选择。

如果您无法生成无重复的结果集,则必须(在性能方面)为消除可能的重复付费。不管是什么,DISTINCT 或 GROUP BY,或者排名函数,它都会导致一些性能损失,你应该接受这个事实。

【讨论】:

    【解决方案2】:

    您需要在表变量的 id 列上创建键。

    这样声明:

    declare @MyTableVariable table(SomeID int identity(1,1) primary key)
    

    此主键将防止重复插入

    希望对你有帮助

    【讨论】:

    • 我的表变量已经指定了一个主键。我不是在问一般如何防止重复,而是在问如何优化查询的性能,而不必恢复到导致整个排序操作的不同子句。
    猜你喜欢
    • 2015-08-07
    • 2016-02-19
    • 2012-08-30
    • 1970-01-01
    • 1970-01-01
    • 2021-09-25
    • 2018-04-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多