首页 > 解决方案 > SQL Server:使用 NULL FK 更快地删除行?

问题描述

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

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

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

随着时间的推移,我们想要清除一些旧数据。但是,事实证明在这种情况下删除速度很慢。经过一番调查,我们发现这是因为一个 FK ( ReferecenId)。所以,我们放弃了 FK。现在,这个表的批量删除要快得多。

FK 来自 table tblReference,它有大约 2 亿行:

ReferenceId, TrafficId, data1, data2, ...

现在,因为我们删除了 FK 以批量删除 中的数据,所以 中的tblTraffic某些行在 中tblReference具有 NULL FK tblTraffic。我们想从tblReference. 中这样的行并不多tblReference

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

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

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

谢谢

标签: c#sqlsql-server

解决方案


作为替代选择,您可以尝试使用LEFT JOINed 与WHERE ... 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(包括潜在的索引 on tblReference.TrafficId):这将防止 RDBMS 在删除期间重新计算索引,如果要删除很多行,这可能会很昂贵。


推荐阅读