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