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'  给其他程序一个时间啊啊啊啊啊啊

  • 相关阅读:
    USACO 3.3 A Game
    USACO 3.3 Camelot
    USACO 3.3 Shopping Offers
    USACO 3.3 TEXT Eulerian Tour中的Cows on Parade一点理解
    USACO 3.3 Riding the Fences
    USACO 3.2 Magic Squares
    USACO 3.2 Stringsobits
    USACO 3.2 Factorials
    USACO 3.2 Contact
    USACO 3.1 Humble Numbers
  • 原文地址:https://www.cnblogs.com/hydor/p/4432959.html
Copyright © 2011-2022 走看看