1. 程式人生 > >記一次SQLSERVER2008R2資料庫查詢超時問題處理

記一次SQLSERVER2008R2資料庫查詢超時問題處理

資料庫環境:

WINDOWS2008R2

SQLSERVER2008R2

應用程式環境:

REDHAT6.5

TOMCAT

JAVA

 

一、故障現象

某系統應用查詢超時

相關SQL:

SELECT v.OBarcode Barcode, v.CBarcode, v.ZID, v.FromName ZNAME, v.ItemName, v.Batch, v.OrderNo, v.SussDate createddate FROM V_TrackAllShipment v (NOLOCK) WHERE 1=1

AND v.OBARCODE = '13436135998'

其中V_TrackAllShipment是一個檢視,且該視圖裡面還有一個檢視,兩個檢視中均運用了大量的union(最多有9個)

該SQL在應用程式查詢超時報錯,無法得到查詢結果,但直接在資料庫中查詢可以在幾秒內得到查詢結果,且結果返回只有幾行資料

二、問題分析

1、嘗試去掉1=1永真條件,查詢依然超時

2、嘗試去掉1=1永真條件,加上1<>1永假條件,幾秒內查詢成功,但返回結果為0行

3、嘗試去掉所有的where條件,幾秒內查詢結果返回50行

 

三、使用profiler跟蹤應用程式查詢SQL

1、跟蹤該SQL後,發現應用程式執行到資料庫的SQL語句發生變化,如下:

SELECT top 50 v.OBarcode Barcode, v.CBarcode, v.ZID, v.FromName ZNAME, v.ItemName, 

v.Batch, v.OrderNo, v.SussDate createddate 

FROM V_TrackAllShipment v (NOLOCK) WHERE 1=1

AND v.OBARCODE = '13436135998'

多了top 50關鍵字

2、分析執行計劃

帶有top 50關鍵字的SQL執行計劃,預估行數達到1億多行,且索引失效

原SQL沒有帶top 50關鍵字的,預估行數只有幾行

四、結論

應用程式在執行SQL的時候,向SQLSERVER資料庫自動添加了top 50關鍵字,導致執行計劃改變,查詢超時

 

五、思考

為何去掉where條件後,查詢結果在幾秒內返回呢?原因在沒有where條件的時候   top 50就只是根據一個ID  選擇前面幾個,但是有where 條件之後,top 50是先需要根據where條件進行查詢出來之後,再把資料進行排序  然後top條資料

 

六、解決方案

1、在應用程式上去掉top 50

2、我嘗試執行UPDATE STATISTICS dbo.tfacsalebarlib WITH FULLSCAN;  進行統計資訊收集後,執行計劃居然變正確了(該表是where條件那個欄位對應所在的表)