我有一个巨大的表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#。
谢谢
答案 0 :(得分:0)
您可以将索引放在前面提到的列上,然后相应地删除(如果您有足够的可用资源)。
如果您为删除操作禁用了不需要的索引,则删除操作也会更快。
如果将删除操作分成多个块,它将更加节省资源。
您还可以考虑使用degree of parallelism
答案 1 :(得分:0)
作为替代选择,您可以尝试结合使用LEFT JOIN
和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
上的所有约束和索引(包括tblReference.TrafficId
上的潜在索引):这将防止RDBMS重新计算索引删除期间,如果要删除的行很多,这可能会很昂贵。