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  还有介样按百分比删除的写法,性能也不是很好。

执行结果:

执行计划:

 

 

 

写法2:

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

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

执行结果:

执行计划:

 

 

 

写法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)先读出来啦,我这里只是示意一下。

执行结果:

 执行计划:

 

结论: 

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

 

提醒自己:

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

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

 

posted @ 2015-04-16 18:50  Hydor  阅读(1072)  评论(0编辑  收藏  举报