我有一张桌子,这取决于其他几张桌子。
当我删除此表中的条目时,我还应删除其“主人”中的条目(它是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
但问题是我不能删除约束,因为插入在其他会话中并行执行。我也无法锁定整个表,因为它非常大,而且这个锁也会锁定很多其他的事务。
我现在找到的唯一方法是为每个外键创建一个索引(可以用来代替PK扫描),但我想完全避免这种扫描(索引与否),因为我确定文档有这样的ID不存在,因为我曾经删除它们。也许有一些提示SQL或某种方法来禁用整个数据库的一个事务insead的引用检查。
答案 0 :(得分:2)
SQL Server在保留参照完整性方面相当顽固,所以不,你不能提示"禁用检查。删除引用行这一事实根本不重要(在高事务环境中,某些进程有足够的时间来修改删除之间的表)。
创建正确的索引是可行的方法。