如何使用多个引用从表中加速删除

时间:2016-07-06 13:51:09

标签: sql-server tsql indexing transactions sql-server-2014

我有一张桌子,这取决于其他几张桌子。

当我删除此表中的条目时,我还应删除其“主人”中的条目(它是1-1关系)。但这是一个问题:当我删除它时,我得到不必要的表扫描,因为它在删除之前检查引用。我确信它是安全的(因为我从OUTPUT子句中得到了ID):

DELETE TOP (@BatchSize) [doc].[Document]
OUTPUT DELETED.A, DELETED.B, DELETED.C, DELETED.D
INTO @DocumentParts
WHERE Id IN (SELECT d.Id FROM @DocumentIds d); 

SET @r = @@ROWCOUNT;    

DELETE [doc].[A]
WHERE Id IN (SELECT DISTINCT dp.A FROM @DocumentParts dp); 

DELETE [doc].[B]
WHERE Id IN (SELECT DISTINCT dp.B FROM @DocumentParts dp); 

DELETE [doc].[C]
WHERE Id IN (SELECT DISTINCT dp.C FROM @DocumentParts dp); 

... several others

但这是我每次删除的计划: enter image description here

如果我从document表计划更改中删除约束: enter image description here

但问题是我不能删除约束,因为插入在其他会话中并行执行。我也无法锁定整个表,因为它非常大,而且这个锁也会锁定很多其他的事务。

我现在找到的唯一方法是为每个外键创建一个索引(可以用来代替PK扫描),但我想完全避免这种扫描(索引与否),因为我确定文档有这样的ID不存在,因为我曾经删除它们。也许有一些提示SQL或某种方法来禁用整个数据库的一个事务insead的引用检查。

1 个答案:

答案 0 :(得分:2)

SQL Server在保留参照完整性方面相当顽固,所以不,你不能提示"禁用检查。删除引用行这一事实根本不重要(在高事务环境中,某些进程有足够的时间来修改删除之间的表)。

创建正确的索引是可行的方法。