使用多线程在SQL Server中删除数据?

时间:2018-12-13 18:30:17

标签: c# .net sql-server

我有一个巨大的表(日志),其中保存一些历史数据。它有10列以上:

Id, Year, Month, Day, data1, data2, data3, ......

由于表很大,因此表上有很多索引和一些FK。

系统不断向该表中插入大量新数据(基于日期)。桌子增长很快。当前,我们使用Windows服务来批量删除旧数据。这就是我们现在正在做的事情。

SET @TotalRows = 0;
SET @Rows = 0;

WHILE 1=1
BEGIN
    DELETE FROM vwTop2K

    SET @Rows = @@ROWCOUNT

    IF(@Rows < @BatchSize)
    BEGIN
        BREAK;
    END

    SET @TotalRows = @TotalRows + @Rows

    IF(@TotalRows >= @DeleteSize)
    BEGIN
        BREAK;
    END

    SET @Rows = 0;
END

vwTop2K是从表中获取前2000行的视图。

它工作正常,但是逐渐地,我们意识到此过程无法足够快地删除数据。由于表很大,因此删除时我们不能删除索引然后重建它。由于表未分区,因此无法使用分区,并且使用分区为现有数据重建表是不切实际的。

因此,最后,我们考虑使用多个线程。该系统由C#编码。这个想法是:我们有10个线程,每个线程调用存储过程在不同的一天进行批量删除,因此线程不会混合在一起。

这是正确的方法吗?还是真的无济于事,因为尽管数据在不同线程中的不同日期,但它们都试图删除同一张大表中的数据?值得付出努力吗?

谢谢

更多信息:

    是,数据库很大,大约4 TB。该表约为1TB。我忘了行数,但是大约超过10亿行
  1. 简单的恢复模型
  2. 每次删除时,删除2000行或5000行,因此将生成巨大的日志文件。每批删除最多删除20万行

1 个答案:

答案 0 :(得分:0)

我的2美分:

您始终可以使用事务隔离级别来使代码并行运行。您的请求之一可能正在阻止其他请求,这给人的印象是代码很慢。实际上,除非进行复杂的查询(如LIKE或CONTAINS),否则删除数百万行不会花很长时间

https://docs.microsoft.com/en-us/sql/t-sql/statements/set-transaction-isolation-level-transact-sql?view=sql-server-2017