MS Sql 优化步骤及优化not in一例

  今天接到客户投诉说系统卡死了,经过一翻努力,终于解决了。现将解决步骤记录一下,以便下次参考:

        因为客户系统集中在阿里云上面,使用的是ms sql2008数据库,上面有N个客户,一下子无法知道是哪个客户。

  第一步,先打开任务管理器,看看cpu使用情况,

一看就知道是 ms sql server有大查询占用了所有的CPU时间,所以卡死系统 。

第二步,打开ms sql server 的活动监控器,查看是哪条语句卡死。

打开活动监控器的方法。在 

中的对象资源管理器,找到服务器,右击。可以看到“活动监控器”,或者用快捷键ctrl+alt+A  .。

 

第三步,找到有问题 的语句。点开进程, 通过任务状态,筛选 running的进程 。

逐个查看运行中的语句,分析最有可能卡住 系统的语句,去运行一下。就可以查到是哪条语句卡住 了。

我的情况就是下面这句:

SELECT A.cCrm, A.cCode AS cOrderCode, A.dRequire, A.dSubmit, B.*,
        C.cCode AS cProductCode, B.cProductSpec BcProductSpec, A.dConfirm,
        A.dCheck1, C.cParamter, C.cSpec AS cProductSpec, C.cColor, A.cCreator
    FROM Orders A WITH ( NOLOCK )
    LEFT JOIN Orders_Product B WITH ( NOLOCK ) ON A.cID = B.cOrdersID
    LEFT JOIN Product C WITH ( NOLOCK ) ON B.cProductID = C.cID
    LEFT JOIN (
                            --生产的产品ID
                SELECT DISTINCT A1.cProductID
                    FROM dbo.Product_Item A1
                    LEFT JOIN dbo.Orders_ProductItem A2 ON A1.cProductID = A2.cProductID
                    WHERE A1.iProduct != 0
              ) D ON B.cProductID = D.cProductID
    WHERE 1 = 1
        AND B.cProductID = D.cProductID
        AND A.iCancel = '0'
        AND ( iStatus = 30
              OR ( iStatus = 20
                   AND iNewCRM != 1
                   AND NOT EXISTS ( SELECT 1
                                        FROM Orders_ProductItem WITH ( NOLOCK )
                                        WHERE iCustom = 1
                                            AND cOrdersID = A.cID )
                 )
            )
        AND ( A.iStatusPP = 0
              OR A.iStatusPP = 1
            )
        AND NOT EXISTS ( SELECT 1
                            FROM MOrders_Product
                            LEFT JOIN dbo.MOrders ON MOrders.cID = MOrders_Product.cMOrdersID
                            WHERE cOrdersProductID = B.cSubID
                                AND dbo.MOrders.iStatus != 2 )
        AND B.iCancelM = 0
        AND B.cSubID NOT IN (
        SELECT B.cOrdersProductID
            FROM DOrders A
            LEFT JOIN DOrders_Sub B ON A.cID = B.cDOrdersID
            WHERE iStatus = 3 )
    ORDER BY A.dUDate DESC; 

经过分析定位到:not in 导至系统卡顿:

 

 B.cSubID NOT IN (
        SELECT B.cOrdersProductID
            FROM DOrders A
            LEFT JOIN DOrders_Sub B ON A.cID = B.cDOrdersID
            WHERE iStatus = 3

 

 将not in 改为 not exists问题得以解决,系统正常运作。

改后的代码为:

SELECT A.cCrm, A.cCode AS cOrderCode, A.dRequire, A.dSubmit, B.*,
        C.cCode AS cProductCode, B.cProductSpec BcProductSpec, A.dConfirm,
        A.dCheck1, C.cParamter, C.cSpec AS cProductSpec, C.cColor, A.cCreator
    FROM Orders A WITH ( NOLOCK )
    LEFT JOIN Orders_Product B WITH ( NOLOCK ) ON A.cID = B.cOrdersID
    LEFT JOIN Product C WITH ( NOLOCK ) ON B.cProductID = C.cID
    LEFT JOIN (
                            --生产的产品ID
                SELECT DISTINCT A1.cProductID
                    FROM dbo.Product_Item A1
                    LEFT JOIN dbo.Orders_ProductItem A2 ON A1.cProductID = A2.cProductID
                    WHERE A1.iProduct != 0
              ) D ON B.cProductID = D.cProductID
    WHERE 1 = 1
        AND B.cProductID = D.cProductID
        AND A.iCancel = '0'
        AND ( iStatus = 30
              OR ( iStatus = 20
                   AND iNewCRM != 1
                   AND NOT EXISTS ( SELECT 1
                                        FROM Orders_ProductItem WITH ( NOLOCK )
                                        WHERE iCustom = 1
                                            AND cOrdersID = A.cID )
                 )
            )
        AND ( A.iStatusPP = 0
              OR A.iStatusPP = 1
            )
        AND NOT EXISTS ( SELECT 1
                            FROM MOrders_Product
                            LEFT JOIN dbo.MOrders ON MOrders.cID = MOrders_Product.cMOrdersID
                            WHERE cOrdersProductID = B.cSubID
                                AND dbo.MOrders.iStatus != 2 )
        AND B.iCancelM = 0
        AND NOT EXISTS (
        SELECT 1
            FROM DOrders AA
            LEFT JOIN DOrders_Sub BB ON AA.cID = BB.cDOrdersID
            WHERE iStatus = 3 AND B.cSubID=bb.cOrdersProductID)
    ORDER BY A.dUDate DESC; 

 

原因可以参考以下文章:

 https://www.cnblogs.com/totian/p/7597300.html

 

 

https://blog.csdn.net/zxu_1995/article/details/82388395

 

posted @ 2019-08-25 12:49  清风笑  阅读(513)  评论(0编辑  收藏  举报