Deleting records with T-SQL efficiently without using IN clause
在下面的场景中,是否有一种不使用关键字
1 2 3 4 5 6 | -- If Documents were deleted, remove them from your ocean DELETE FROM IndexHistory WHERE DocId IN (SELECT IH.Docid FROM IndexHistory IH LEFT JOIN IndexedLineItems I ON IH.Docid = I.DocId WHERE I.Docid IS NULL) |
如果您研究这个场景,您将在圆括号内从查询中删除所有记录。
事实证明,使用"in"是低效的。所以有人会认为应该有一种方法删除这些没有"in",因为您的所有记录都可以识别,而不使用"in"。
例如,我认为这样的事情是可能的,但是我没有正确的语法:
1 2 3 | DELETE FROM IndexHistory IH LEFT JOIN IndexedLineItems I ON IH.Docid = I.DocId WHERE I.Docid IS NULL |
号
我很感激你的回答仍然是"不,不可能"。
如果这是不可能的,也许这是一个可能的建议,以改善语言为微软。在我这样做之前,我想我会在这里发帖看看我是否遗漏了什么。
使用
1 2 | Delete ih from IndexHistory ih where not exists (select 1 from IndexedLineItems ili where ih.Docid = ili.DocId) |
号
由于可读性原因,我更喜欢CTE,它也可以更改为使用
1 2 3 4 5 6 7 8 | WITH DeleteData AS ( SELECT IH.Docid FROM IndexHistory IH WHERE NOT EXISTS( SELECT 1 FROM IndexedLineItems I WHERE I.DocId = IH.DocId) ) DELETE FROM DeleteData |
您不需要从该CTE到表的附加联接,因为只选择了一个表。
在另一种想法中,使用内部联接,因此只删除匹配项:
1 2 3 | DELETE FROM IndexHistory IH JOIN IndexedLineItems I ON IH.Docid = I.DocId WHERE I.Docid IS NOT NULL |
这很管用…
1 2 3 4 5 | DELETE IH FROM IndexHistory IH Left JOIN IndexedLineItems LI ON IH.Docid = LI.DocId WHERE LI.DocId is Null |
。