使用 DELETE 逻辑不在嵌套查询中的最快性能 [重复]

Posted

技术标签:

【中文标题】使用 DELETE 逻辑不在嵌套查询中的最快性能 [重复]【英文标题】:Fastest performance with DELETE logic NOT IN nested query [duplicate] 【发布时间】:2013-04-19 03:17:37 【问题描述】:

我正在尝试为这个 DELETE(和 SELECT)查询获得最快的性能。有没有更好的方法来删除记录,因为这需要 10 多分钟才能运行?我想它必须进行自己的排序和合并,直到找到记录为止。

SELECT COUNT([VISIT_ID])
FROM [dbo].[I2B2_SRC_VISITS]
WHERE [PATIENT_ID] NOT IN (
    SELECT [PATIENT_ID] FROM [dbo].[I2B2_SRC_PATIENT]
)

DELETE FROM [dbo].[I2B2_SRC_VISITS]
WHERE [PATIENT_ID] NOT IN (
    SELECT [PATIENT_ID] FROM [dbo].[I2B2_SRC_PATIENT]
)

编辑:我不能像使用 SELECT 那样将 DELETE 放在该查询的前面。但这是 DELETE 语句的最终结果。

DELETE FROM [dbo].[I2B2_SRC_VISITS]
WHERE [VISIT_ID] IN
(
    SELECT a.[VISIT_ID]
    FROM    [dbo].[I2B2_SRC_VISITS] a
            LEFT JOIN [dbo].[I2B2_SRC_PATIENT] b
                ON a.[PATIENT_ID] = b.[PATIENT_ID]
    WHERE b.[PATIENT_ID]  IS NULL
)

【问题讨论】:

ExplainExtended BlogSQLAuthority 和许多其他在线文献将引导您走向您已经写过的不存在/不存在。但是,总是有例外,例如当您没有必要的索引时(有时可能是有效的)。始终尝试尽可能多的形式,并使用最有效的形式。不过,对于小型数据集,这可能无关紧要。 【参考方案1】:

通过JOIN 来做怎么样?

DELETE  a
FROM    [dbo].[I2B2_SRC_VISITS] a
        LEFT JOIN [dbo].[I2B2_SRC_PATIENT] b
            ON a.[PATIENT_ID] = b.[PATIENT_ID]
WHERE   b.[PATIENT_ID] IS NULL

确保两个表中的 [PATIENT_ID] 列都有键定义,这样会更快。


没错。 NOT EXIST 更好。

DELETE  a 
FROM    [dbo].[I2B2_SRC_VISITS] a 
WHERE   NOT EXISTS
        ( 
            SELECT  1 
            FROM    [dbo].[I2B2_SRC_PATIENT] b
            WHERE   a.[PATIENT_ID] = b.[PATIENT_ID] 
        )

【讨论】:

也可以使用NOT EXIST试试这个语法:DELETE a FROM [dbo].[I2B2_SRC_VISITS] a WHERE NOT EXIST ( SELECT 1 FROM [dbo].[I2B2_SRC_PATIENT] b WHERE a.[PATIENT_ID] = b.[PATIENT_ID] ) 可能 - 行数不足以达到临界点。见sqlperformance.com/2012/12/t-sql-queries/left-anti-semi-join @JW 你确定他们是同一个计划吗?我看到一个带有 NOT EXISTS 和反半连接的额外 TOP 运算符。另一个具有 LEFT OUTER JOIN,看起来它实现了行和随后的过滤器。根据问题检查我评论中的第一个链接。 @AaronBertrand 对。就在这里。 NOT EXISTS 更好sqlfiddle.com/#!3/244f5/1 @JW 一个提示。对于这样的 2 个查询,尽管查询优化器会发出所有不准确和谎言,但您可以通过将其设为单个批次来查看它们的相对估计成本,例如sqlfiddle.com/#!3/244f5/2/0。 (单一)计划同时显示了两个查询,现在更容易比较成本。

以上是关于使用 DELETE 逻辑不在嵌套查询中的最快性能 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

关于SQL DELETE嵌套子查询问题

如何提高 SQL Server 查询的性能以选择具有值的行不在子查询中的一次计数

SQL Server 之 子查询与嵌套查询

跳出嵌套循环

SQL查询中INSERT、DELETE、UPDATE的逻辑查询处理阶段

sql语句中where条件的嵌套子查询性能