天天看點

第11/24周 重編譯

今天我想談下性能調優教育訓練裡的重編譯(Recompilations )。當你執行一個查詢,SQL Server裡另一個變動使你執行計劃的剩餘部分無效,就會發生重編譯。在那個情況下SQL Server需要保證你執行計劃的準确性,重編譯就會被觸發。重編譯會給你的SQL Server帶來額外的CPU開銷。

什麼是重編譯?

首先我想展示下編譯和重編譯之間的差別。2個星期前,我們讨論了SQL Server裡的編譯。當查詢優化器把送出的查詢轉化為實際執行計劃時,編譯就會發生。這就是說編譯在查詢執行開始前就發生。

另一方面,重編譯在查詢執行期間就會發生。是以SQL為了保證執行計劃的準确性就重編譯執行計劃的剩餘部分。如果執行計劃裡引用的索引在計劃執行時被删除了。這就導緻不可接受的結果。SQL Server觸發重編譯有2個類型:

  • 基于正确性的重編譯(Correctness-based Recompilations)
  • 基于最優性能的重編譯(Optimality-based Recompilations)

我們來詳細看下這2類重編譯。當計劃不再準确,就會發生基于正确性的重編譯(Correctness-based Recompilations)。例如你的資料庫架構發生改變(新增或删除索引,删除統計資訊),或者你的SET選項發生改變。在那個情況下,重編譯就是為了保證你計劃的準确。

如果你的統計資訊發生改變,就會發生基于最優性能的重編譯(Optimality-based Recompilations)。統計資訊發生改變,一方面是SQL Server會自動更新你的統計資訊,另一方面是你觸發了統計資訊的人為更新。那樣的情況可以是書簽查找正越過臨界點,SQL Server需要引入全表/聚集索引掃描。

我們現在再來詳細看一個在查詢執行期間,觸發很多重編譯的常見特殊情景——臨時表(Temp Tables)!

臨時表(Temp Tables)

是的,你沒看錯:當你與臨時表(Temp Tables)打交道時,在SQL Server裡你會引起重編譯。我們來一個非常簡單的存儲過程定義:

1 CREATE PROCEDURE DoWork
 2 AS
 3 BEGIN
 4    CREATE TABLE #TempTable
 5    (
 6       ID INT IDENTITY(1, 1) PRIMARY KEY,
 7       FirstName CHAR(4000),
 8       LastName CHAR(4000)
 9    )
10    INSERT INTO #TempTable (FirstName, LastName)
11    SELECT TOP 1000 name, name FROM master.dbo.syscolumns
12    SELECT * FROM #TempTable
13 END
14 
15 GO      

這個存儲過程建立了一個簡單的臨時表,往它裡面插入了幾條記錄,最後從表裡擷取幾條記錄。很簡單,是不是?關鍵是這個存儲過程在執行期間觸發了2個重編譯:

  • 第1個觸發重編譯是因為你建立了一個新的臨時表。通過建立臨時表你就在改變你的資料庫架構。這個觸發了基于正确性的重編譯(Correctness-based Recompilations)。
  • 當你執行SELECT語句時,你觸發了第2個重編譯。剛才你在臨時表裡插入了幾條記錄,是以SQL Server需要更新你的統計資訊。這裡你就引入了基于最優性能的重編譯(Optimality-based Recompilations)。

如何避免這2個重編譯呢?你可以使用表變量(Table Variables)代替臨時表。用表變量的話,你就不再改變資料庫架構了(它隻是個變量),而且表變量是沒有統計資訊的。這2個重編譯就消失了。但是當然,用表變量會引入另一個性能問題:因為它們沒有統計資訊,SQL Server總是估計它們隻有1行,是以你的基數預估就會完全一塌糊塗。

是以表變量在SQL Server裡隻有特殊使用情景:當你隻和小量資料打交道時。當你和大量資料打交道時,你仍應該使用臨時表,因為它們會給你準确的統計資訊,你也可以在上面建立索引。缺點就是它們會觸發重編譯。

小結

今天我們讨論了性能調優教育訓練裡的重編譯(Recompilations)。如你所見,因為SQL Server需要保證你的執行計劃的準确性才會有重編譯發生。我們還看了重編譯經常發生的特殊場景——臨時表(Temp Tables)。探秘重編譯(Recompilations)(1/2) 探秘重編譯(Recompilations)(2/2)

這些重編譯可以通過使用表變量來解決,但這裡你也要意識到帶來的副作用。下星期我會談下SQL Server裡的并行執行計劃(Parallel Execution Plans),裡面會有很多有趣的事情發生。好好享受接下來的7天,到時候見! 

圍觀PPT:

0803_11_重編譯.rar

注:此文章為

WoodyTu

學習MS SQL技術,收集整理相關文檔撰寫,歡迎轉載,請在文章頁面明顯位置給出此文連結!

若您覺得這篇文章還不錯請點選下右下角的推薦,有了您的支援才能激發作者更大的寫作熱情,非常感謝!

繼續閱讀