zoukankan      html  css  js  c++  java
  • 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'  给其他程序一个时间啊啊啊啊啊啊

  • 相关阅读:
    蛋疼的springboot web项目使用jetty容器运行
    freemark 异常
    系统中个别页面间断性跳转到登录页异常
    Spring Transaction 使用入门
    单例模式
    抽象工厂模式
    工厂模式
    设计模式
    关于ZK框架的onScroll事件的问题
    关于CheckStyle在eclipse出现的问题
  • 原文地址:https://www.cnblogs.com/hydor/p/4432959.html
Copyright © 2011-2022 走看看