• sql server 之一条Sql语句引发的悲剧


      最近在一个比较古老的项目中,使用的是sql server 2000(sp4) 企业版,是用DotNet2.0开发的WinForm项目。实施后,运行刚开始,一直很正常,但是过了一段时间后,可能是当数据达到一定量的时候,出现一个奇怪的问题:数据库连接不上了!

      于是,想在数据库服务器上来查找原因,发现在服务器上也无法连接到数据库。一样的出现“连接超时错误”,更晕的是当我想停止数据库服务时,发现显示的状态是”停止“,但是“服务管理器”下面的状态一直显示“正在停止...", 而上面的“开始”,“暂停”,“停止”三个按钮都是灰色无法点击的状态。查看进程,发现”sqlserver.exe"这个进程还在,并且使用的cpu一会是0一会跳到25,说明它还在运行!实在是没辙了,重启机器!

      重启后,数据库可以访问了,貌似恢复正常。但是过了半天,又出现上面的情况,实在是太郁闷了!数据库日志也没有记录什么有用的信息,关键是无法连接到数据库,问题都没法查!换台数据库服务器试试看,结果也是问题依旧!

      凭感觉,应该是sql2000里面的进程出现了阻塞或者死锁。阻塞在数据库服务中是常事,但是一般情况下只是速度慢而已,很少会连数据库整个挂掉。应该是死锁!

      难道是程序中连接没有及时断开导致的?于是检查了程序,发现连接都是在访问之后都已经close掉了,这就比较棘手了!通过sp_who等检查性能,也没有发现任何有价值的线索。

      这样的问题大概出现了十多天,问题查找一直无果,每次出现问题只有重启。用户一大堆的埋怨不说,自己也心力交瘁!

      这样下去肯定不是办法,于是从前端操作下手,先找出出现问题的时机。通过操作此系统N多功能,最后发现了每次出现问题都是在一个打印操作完之后,另外一个人如果再次打印就会出现“连接超时错误”,但是第三次打印又可以连接到数据库,如此循环下去,最后就出现任何连接到数据库的操作都超时。这问题太奇怪了!只有去看打印功能的源代码了。经过Debug,发现:出现超时错误时,都是在执行下面这个SQL语句时出现的:

    SELECT  EMPID,MONTH(OVERDATE),SUM(OVERHOURS) AS MONTHSUM 
    ,(SELECT SUM(OVERHOURS) AS YEARSUM FROM OVERINPUT WHERE EMPID=OVERINPUT.EMPID
        AND YEAR(OVERDATE)=2012
    ) AS YEARSUM
    FROM OVERINPUT
    WHERE MONTH(OVERDATE) BETWEEN 1 AND 6
    GROUP BY EMPID,MONTH(OVERDATE)
    ORDER BY EMPID,MONTH(OVERDATE)

       这是一个打印加班统计信息的SQL,每次执行打印功能,系统按照部门数量循环(for)调用了20次左右,以打出每个部门的加班统计情况。下面是SQL中涉及到的表和字段的含义:

       OVERINPUT(加班记录表) ,EMPID员工号),OverDate(加班日期) OverHours(加班小时数)

     所以上面的SQL是统计每个员工1-6月中每个月的加班总数,还有当年(2012)的加班总数,作者的目的是不想重新再查一遍年度的合计加班数,把它们混在一起

    。现在这条查询语句不定时的查询超时,先优化一下:那最直接的肯定是将YEARSUM这段代码用简单的常量代替处理:

    SELECT  EMPID,MONTH(OVERDATE),SUM(OVERHOURS) AS MONTHSUM 
    /*
    ,(SELECT SUM(OVERHOURS) AS YEARSUM FROM OVERINPUT WHERE EMPID=OVERINPUT.EMPID
        AND YEAR(OVERDATE)=2012
    ) AS YEARSUM
    */
    ,1 AS YEARSUM
    FROM OVERINPUT
    WHERE MONTH(OVERDATE) BETWEEN 1 AND 6
    GROUP BY EMPID,MONTH(OVERDATE)
    ORDER BY EMPID,MONTH(OVERDATE)

      当然,这样的最后打印出来的结果肯定不对,反正先测试着,看数据库还会不会死?让人意想不到的是,结果数据库一直都正常!这也太奇怪了!即使查询速度效率低,但是为什么会连数据库都死掉了呢?还有上面的方法问题是解决了,但是效率太低!类似的问题,要怎么从数据库上查找原因? 也希望有SQL牛人能指点迷津!

      

      

  • 相关阅读:
    Atitit. 衡量项目规模 包含的类的数量 .net java类库包含多少类 多少个api方法??
    Drawable 中getIntrinsicWidth
    js播放音乐
    Parcelable和Parcel
    标题栏和状态栏
    android振动效果的实现
    Android位置服务和Google地图API初解
    TranslateAnimation详解
    android真机调试
    常见的Android图标大小
  • 原文地址:https://www.cnblogs.com/lane_yang/p/2526461.html
Copyright © 2020-2023  润新知