ADO.NET 使用DELETE语句批量删除操作,提示超时,删除失败,几种优化解决思路

时间:2023-03-09 14:21:24
ADO.NET 使用DELETE语句批量删除操作,提示超时,删除失败,几种优化解决思路

起因是如此简单的一句sql

DELETE FROM tablename  WHERE timekey=20150416

提示:Timeout 时间已到。在操作完成之前超时时间已过或服务器未响应。

提供几种解决思路:

1、检查WHERE条件中字段是否已建索引

2、检查是否被其他表引用,引用表外键字段上是否已建索引

3、分批次删除,根据容量大小设置条数

4、重建索引

第3点,稍微展开一下:

写法1:

首先我们能想到的分批肯定是 TOP

DELETE TOP(5000)  FROM tablename  WHERE timekey=20150416

top多少合适呢,具体还要根据实际场景自己试。

条数多了会造成锁阻塞,即使条数少了也不是没有阻塞可能的,而且听说频繁的删除操作会造成相同语句的IO差距很大,比较不稳定,没有亲自试,不知道传闻是不是真的。

*注:DELETE TOP(10) PERCENT  还有介样按百分比删除的写法,性能也不是很好。

执行结果:

ADO.NET 使用DELETE语句批量删除操作,提示超时,删除失败,几种优化解决思路

执行计划:

ADO.NET 使用DELETE语句批量删除操作,提示超时,删除失败,几种优化解决思路

写法2:

有自增列且自增列有索引的情况下,分两步走,①取一批次ID,②删除

DELETE FROM tablename  WHERE ID IN (54321,54322,54323......5000个ID...)

执行结果:

ADO.NET 使用DELETE语句批量删除操作,提示超时,删除失败,几种优化解决思路

执行计划:

ADO.NET 使用DELETE语句批量删除操作,提示超时,删除失败,几种优化解决思路

写法3:

有自增列且自增列有索引的情况下,根据MIN(ID),MAX(ID)区间分批次删除。

DELETE FROM tablename
WHERE
ID>=MIN(ID)+5000
and ID<MIN(ID)+10000
and ID<=MAX(ID)
and timekey=20150416

当然,最好是将MIN(ID),MAX(ID)先读出来啦,我这里只是示意一下。

执行结果:

ADO.NET 使用DELETE语句批量删除操作,提示超时,删除失败,几种优化解决思路

执行计划:

ADO.NET 使用DELETE语句批量删除操作,提示超时,删除失败,几种优化解决思路

结论:

写法3在各方面都更为优质。当然这个结论是基于我的表约3000w条数据,每批5000条删除的情况,不排除其他场景下的会得到其他结论的可能。没有万能的语句,大家还是要自己试的啊。

提醒自己:

1、select min 和 max id 的时候记得写 with(nolock)啊啊啊

2、删除间隙记得 WAITFOR DELAY '0:0:1'  给其他程序一个时间啊啊啊啊啊啊