以下查詢花費約1分鐘的運行,並具有以下IO統計:查詢執行除非很差一個臨時表用於
SELECT T.RGN, T.CD, T.FUND_CD, T.TRDT, SUM(T2.UNITS) AS TotalUnits
FROM dbo.TRANS AS T
JOIN dbo.TRANS AS T2 ON T2.RGN=T.RGN AND T2.CD=T.CD AND T2.FUND_CD=T.FUND_CD AND T2.TRDT<=T.TRDT
JOIN TASK_REQUESTS AS T3 ON T3.CD=T.CD AND T3.RGN=T.RGN AND T3.TASK = 'UPDATE_MEM_BAL'
GROUP BY T.RGN, T.CD, T.FUND_CD, T.TRDT
(4447行(一個或多個)受影響) 表「交易」。掃描計數5977,邏輯讀取7527408,物理讀取0,預讀讀取0,lob邏輯讀取0,lob物理讀取0,lob預讀取讀取0. 表'TASK_REQUESTS'。掃描計數1,邏輯讀取11,物理讀取0,預讀讀取0,lob邏輯讀取0,lob物理讀取0,lob預讀取讀取0.
SQL Server執行時間: CPU時間= 58157 ms ,經過時間= 61437毫秒。
如果我代替引入一個臨時表,則該查詢將快速返回,並執行以下邏輯讀取:
CREATE TABLE #MyTable(RGN VARCHAR(20) NOT NULL, CD VARCHAR(20) NOT NULL, PRIMARY KEY([RGN],[CD]));
INSERT INTO #MyTable(RGN, CD) SELECT RGN, CD FROM TASK_REQUESTS WHERE TASK='UPDATE_MEM_BAL';
SELECT T.RGN, T.CD, T.FUND_CD, T.TRDT, SUM(T2.UNITS) AS TotalUnits
FROM dbo.TRANS AS T
JOIN dbo.TRANS AS T2 ON T2.RGN=T.RGN AND T2.CD=T.CD AND T2.FUND_CD=T.FUND_CD AND T2.TRDT<=T.TRDT
JOIN #MyTable AS T3 ON T3.CD=T.CD AND T3.RGN=T.RGN
GROUP BY T.RGN, T.CD, T.FUND_CD, T.TRDT
(4447行(一個或多個)受影響) 表「工作臺」。掃描計數5974,邏輯讀取382339,物理讀取0,預讀讀取0,lob邏輯讀取0,lob物理讀取0,lob預讀讀取0. 表'TRANSACTIONS'。掃描計數4,邏輯讀取4547,物理讀取0,預讀讀取0,lob邏輯讀取0,lob物理讀取0,lob預讀讀取0. 表'#MyTable ____________________________________________________________________________________________________ 000000000013'。掃描計數1,邏輯讀取2,物理讀取0,預讀讀取0,lob邏輯讀取0,lob物理讀取0,lob預讀取讀取0.
SQL Server執行時間: CPU時間= 1420 ms ,經過時間= 1515毫秒。
對我來說有趣的是,TASK_REQUEST表是一個小表(目前有3行),統計信息在表中是最新的。任何想法爲什麼這種不同的執行計劃和執行時間會發生?理想情況下如何改變事情,以便我不需要使用臨時表來獲得體面的表現?
執行計劃中唯一真正的區別是臨時表版本引入了索引假脫機(eager spool)操作。
是否運行每個查詢,以確保一個公平的比較之前清空緩存? – 2010-06-08 20:42:15
我已經使用clean procedure cache和clean buffers以及熱緩存和緩衝區來運行比較。沒有區別。 – 2010-06-08 20:58:23
您對TRANS和TASK_REQUESTS有哪些索引?您在#myTable上創建的主鍵是否與TASK_REQUESTS中的內容匹配? – 2010-06-08 21:25:01