2012年7月24日 星期二

FN_TRACE_GETTABLE函數配上WHERE發生的怪事


        最近在某台SQL 2005的機器上啟用Server Side Trace,打算自動分析Trace檔來稽核軌跡紀錄,因為FN_TRACE_GETTABLE函數本身可以以表格式格式傳回Trace檔的內容,我就偷懶直接拿來過濾欄位使用,沒有先匯入資料表後再過濾,結果發生同樣的指令有時候有回傳資料,有時候又沒有資料的情況

        同樣讀取4Trace檔案,假設20萬筆紀錄,同樣的過濾條件,第一次得花2秒執行完,第二次以後只要花0.5秒就執行完了,第二次比第一次快是因為資料都載入記憶體,可以理解會加快速度,問題是第一次執行回傳16筆資料,第二次之後竟回傳0筆資料,我是見鬼了嗎?如下圖,我用Profiler錄製的內容,總共執行6次



        前五次錄到指令都一樣,如下(沒有最後的RECOMPILE查詢提示),但只有第一次傳回16筆紀錄,其餘4次都是回傳0筆紀錄,很怪,第六次我有加上最後的RECOMPILE查詢提示就又正常回傳16筆紀錄囉

SELECT *
FROM  FN_TRACE_GETTABLE(N'D:\SQLtrace\trace.trc', 4)
where left(LoginName,3) = 'mit' and (ApplicationName <> 'Microsoft SQL Server Management Studio - 查詢'
and  ApplicationName <> 'Microsoft SQL Server Management Studio'
and  ApplicationName <> 'SQL Server Enterprise Manager'
and  ApplicationName <> 'Microsoft SQL Server'
and  ApplicationName <> 'Microsoft® Visual Studio® 2005'
and  ApplicationName <> 'SQL Query Analyzer'
and  ApplicationName <> 'SQL Query Analyzer - 物件瀏覽器')
OPTION(RECOMPILE)

        我一直找不到是什麼原因造成的,像此例有一大串的ApplicationName才會怪怪的,若拿掉只剩LoginName也正常,沒有WHERE的情況也正常!這樣看似跟篩選條件有關係,但若加上RECOMPILE查詢提示就全都正常了,很怪吧!

        加上RECOMPILE就正常,很像是執行計畫不同的關係,但執行計畫不同並不會影響回傳結果的啊!不是嗎!

        還有如果一開始就先匯入資料表就不會遇到這樣的怪事囉!

0 意見:

張貼留言