使用带有 DELETE 的 T-SQL EXCEPT / 优化查询
Posted
技术标签:
【中文标题】使用带有 DELETE 的 T-SQL EXCEPT / 优化查询【英文标题】:Using T-SQL EXCEPT with DELETE / Optimizing a query 【发布时间】:2017-03-31 14:39:05 【问题描述】:以下代码从表中删除与非活动项目相关的任务记录。
delete from [Deliverables] where
[Deliverables].[ProjectID] not in
(
select
[ProjectID] from [ActiveProjects]
)
我在某处读到,将NOT IN
与返回大量值的子查询一起使用并不是最有效的做法,最好使用EXCEPT
子句。
但是,当我尝试使用以下代码时,出现错误(关键字“except”附近的语法不正确。)
delete from [Deliverables]
except
select * from [Deliverables], [ActiveProjects]
where [Deliverables].[ProjectID] = [ActiveProjects].[ProjectID]
如何将EXCEPT
与DELETE
一起使用?如果我不能,有什么方法可以优化我的查询以更快地执行?
【问题讨论】:
【参考方案1】:您也可以尝试not exists
,脚本如下所示:
delete from [Deliverables]
where not exists
(select 1
from [ActiveProjects]
where [ActiveProjects].[ProjectID] = [Deliverables].[ProjectID])
如果[ActiveProjects]中有很多数据,那应该是更好的解决方案,但是它是所有数据依赖的,所以请在使用前测试效率。
【讨论】:
这个解决方案对我有用,它比使用 NOT IN 子句要快得多。谢谢! 这是一个不错的解决方案(我赞成),但并没有真正回答有关 EXISTS 部分的问题。 EXISTS 与 SELECT 语句一起使用。将它与 DELETE 一起使用的唯一方法是,如果您还按照其他解决方案中所示的方式执行 JOIN(这是我试图避免的)。另见:***.com/q/55423803/2949093【参考方案2】:像这样尝试(通过添加 where 子句和列名等来修改您的需要)
delete from table1
from table1 a
inner join
( select your_column
from table1
except
select your_column
from table2
) b
on a.your_column = b.your_column;
【讨论】:
【参考方案3】:delete d
from [Deliverables] as d
inner join (
select d2.[ProjectId] from [Deliverables] as d2
EXCEPT
select ap.[ProjectId] from [ActiveProjects] as ap
as todel on
((todel.[ProjectId] is NULL) and (d.[ProjectId] is NULL))
or todel.[ProjectId] = d.[ProjectId]
一个微妙之处:关于 EXCEPT 的好处是它将等同于 NULL 值,而不是决定它们永远不匹配(就像“=”那样)。在您的简单示例(仅查看 id)中,这不太可能有价值,但是如果您正在比较允许空值的表的较大部分,您将不得不考虑这种尴尬的“空匹配”或错过很多行。
【讨论】:
以上是关于使用带有 DELETE 的 T-SQL EXCEPT / 优化查询的主要内容,如果未能解决你的问题,请参考以下文章
T-SQL INSTEAD OF DELETE 触发器在没有“挑衅”的情况下触发