SQL Server:使用NULL FK删除行的速度更快?

时间:2018-12-17 17:10:47

标签: c# sql sql-server

我有一个巨大的表tblTraffic,其中有很多列:

Id, date, year, month, day, ReferenceId, data1, data2, data3....

该表有超过10亿行,大小约为1TB。它还具有许多索引和FK。

随着时间的流逝,我们想清除一些旧数据。但是,事实证明在这种情况下删除速度很慢。经过调查,我们发现这是由于一个FK(ReferecenId)引起的。因此,我们删除FK。现在,此表的批量删除要快得多。

FK来自表tblReference,该表具有约2亿行:

ReferenceId, TrafficId, data1, data2, ...

现在,由于我们丢弃FK来批量删除tblTraffic中的数据,因此tblReference中的某些行在tblTraffic中具有NULL FK。我们要从tblReference中删除所有这些。 tblReference中没有这样的行。

DELETE *
FROM tblReference 
WHERE NOT EXISTS (SELECT 1
                  FROM tblTraffic
                  WHERE tblTraffic.Id = tblReference.TrafficId)

为此,我们尝试批量删除,但是速度很慢。有什么建议吗?

我们正在使用SQL Server和C#。

谢谢

2 个答案:

答案 0 :(得分:0)

您可以将索引放在前面提到的列上,然后相应地删除(如果您有足够的可用资源)。

如果您为删除操作禁用了不需要的索引,则删除操作也会更快。

如果将删除操作分成多个块,它将更加节省资源。

您还可以考虑使用degree of parallelism

答案 1 :(得分:0)

作为替代选择,您可以尝试结合使用LEFT JOINWHERE ... IS NULL

DELETE ref
FROM 
    tblReference ref
    LEFT JOIN tblTraffic tra
        ON tra.Id = ref.TrafficId
WHERE tra.TrafficId IS NULL

根据您实际的数据库设置,它的执行速度可能比嵌套子查询快。

我还建议在运行此查询之前在表Id的列tblTraffic上建立索引。

另一种优化方法是在tblReference期间临时禁用表DELETE上的所有约束和索引(包括tblReference.TrafficId上的潜在索引):这将防止RDBMS重新计算索引删除期间,如果要删除的行很多,这可能会很昂贵。