1. 程式人生 > >理解記憶體----優化SQL Server記憶體配置

理解記憶體----優化SQL Server記憶體配置

最小和最大Server記憶體

Min Server Memory (MB) 和 Max Server Memory (MB)控制所有SQL Server記憶體使用的許可大小。比起之前的版本,SQL Server 2012的Memory Manager可以更簡單地設定SQL Server記憶體需求的大小。SQL Server服務是以所需的最小量啟動的,並根據需要增長。一旦記憶體使用增長超過Min Server Memory設定,SQL Server將不會釋放任何低於該量的記憶體。Min Server Memory設定記憶體使用的下限,而Max Server Memory則設定上限。這兩個值可以使用sp_configure或通過Management Studio中的SQL Server屬性視窗的記憶體頁面進行設定。兩個設定中,配置緩衝池的最大值更重要,它會阻止SQL Server佔用過多的記憶體。這在64位系統中尤其重要,因為缺少可用實體記憶體能夠導致Windows裁剪SQL Server的工作集。後面的“鎖定記憶體頁”有關於這個問題的完整描述。對於配置Max Server Memory,有一些不同的方法來計算合適的值,最直接的方法是看看SQL Server的最大使用量,及確定SQL Server之外記憶體需求的最大潛在用量。

檢視SQL Server的最大使用量

設定SQL Server動態管理記憶體,然後使用效能監視器監視計數器MSSQL$<instance>:Memory Manager\Total ServerMemory (KB)。這個計數器測量SQL Server的總緩衝池使用量。如果SQL Server以外的其他需求需要比當前可用記憶體更多的實體記憶體時,Total Server Memory值會降低,然後使用任何可用記憶體再增加。如果您監視此計數器一段時間(包括忙時和淡時),然後你就可以將Max Server Memory設定為你觀察到的Total Server Memory (KB)的最低值,你不必擔心SQL Server在正常操作期間收縮它的使用量。

確定SQL Server之外記憶體需求的最大潛在用量

此選項是最流行的,因為其目的是計算出最壞的情況下,除SQL Server之外的記憶體需求。你應該考慮如下情況:

  • 2GB用於Windows
  • xGB用於SQL Server工作執行緒。你可以查詢sys.dm_os_sys_info來獲取最大工作執行緒數,每個執行緒會使用0.5MB(在x86系統),2MB(在x64)
  • 512MB,如果你用Linked servers、擴充套件儲存過程dll,或通過自動化程式(Automation     procedures (sp_OA calls))建立的物件
  • 1~3GB,用於其他可能再系統上執行的應用程式,如備份程式或反病毒軟體

例如,在一個有8個CPU核心、64GB RAM、執行SQL Server 2012、一個第三方備份工具和病毒檢測程式的伺服器上,你將考慮如下情況:

  • 2GB用於Windows
  • 1GB用於工作執行緒(576     X 2MB四捨五入)
  • 512MB用於Linked Server等
  • 1GB用於備份程式和病毒檢測程式

共計4.5GB,你可以將Max Server Memory配置為59.5GB

檢查你的Max Server Memory是否有效

當你建立一個伺服器時決定要如何配置max server memory,沒有伺服器執行它期望的負載時衡量其有效性並調整它重要。要做到這一點,一個簡單的方法是使用效能監視器計數器,具體地說,MSSQL$<instance>:Buffer Manager\Page LifeExpectancy (PLE)和Memory\Available MBytes。這兩個計數器之間的平衡將告訴您max server memory設定有多大效力。PLE顯示了SQL Server希望一個頁面保持在資料快取中多少秒,它是一個好的衡量SQL Server記憶體壓力的辦法。Available MBytes顯示了Windows有多少可用的物理RAM。

如果你的PLE低(<300),就檢查Available MBytes,看看有多少未使用的記憶體可用。如果可用的少於5MB,Windows就會開始侵略性地裁剪所有的應用程式的工作集,這被認為是一個緊急問題。如果PLE低,並且你有大量Available MBytes,你就應該增大Max Server Memory的設定,從而增加PLE;相反,如果Available MBytes低,而PLE很高,那麼你就應該降低Max Server Memory設定,從而把一些RAM返還給Windows。下面是一些示例場景來說明這一點:

  • 有32GB RAM的伺服器Max Server Memory是30GB,PLE平均為10000,Available MBytes是90MB。解決方案:至少降低Max     Server Memory 500MB。
  • 有50GB RAM的伺服器Max Server Memory是46GB,PLE平均是10,Available MBytes是1500MB。解決方案:增加Max     Server Memory 500MB到1000MB。
  • 有64GB RAM的伺服器Max Server Memory是60GB,PLE平均是50,Available MBytes是20MB。解決方案:降低Max     Server Memory 100MB,併購買更多RAM(儘快)。

Lock Pages in Memory

Lock Pages in Memory (LPIM)被用作應急措施(work-around),當Windows和SQL Server之間發生錯誤時,這在舊版本的SQLServer上特別不好。如果Windows沒有足夠的可用實體記憶體,服務來至來自驅動器或其他應用程式的資源請求,Windows將會裁剪在伺服器上執行的所有應用程式的工作集(它指的是一個程序的實體記憶體使用情況)。這是正常的行為,應該不會有太顯著的影響。Windows Server 2003中並沒有很好地處理寫得很糟糕的驅動程式(badly written drivers),實際上可以強制所有的應用程式清空他們的工作集。這就是所謂的侵略性工作集裁剪(aggressive working set trimming),它對SQL Server的記憶體分配有破壞性的影響 - 因此影響效能。所以,你可以看到,當發生這種情況時,微軟增加了一個訊息到SQL Server錯誤日誌。下面是一個例子:

A significant part of sql server process memory hasbeen paged out.This may result in a performance degradation. Duration: 0seconds.Working set (KB): 1086400, committed (KB): 2160928, memory utilization:50%.

在Windows Server 2008中,這種行為得到顯著改變,防止了最大的問題--寫得很糟糕的驅動程式引起的應用程式工作集被清空。這不會影響SQL Server 2012,因為它只執行在Windows Server 2008+中。在SQL Server 2012中,當Windows執行工作集裁剪時,你仍然會得到記錄的訊息。幾個訊息能夠表明SQL Server的工作集逐漸下降(這仍然是個問題)。有兩種方式解決這個問題:

  • 恰當地設定Max Server Memory,確保Windows和伺服器上執行的其他程序有足夠的實體記憶體來執行它們的工作,而不必要求SQL Server裁剪。
  • 如果你仍然看到的問題(或者,如果它的影響是非常嚴重,你不想再冒險見到它),你可以使用Locked Pages in Memory     (LPIM)來配置你的SQL Server。

當LPIM啟用,SQL Server的緩衝池頁面是“鎖定”且不可分頁的(non-pageable),因此Windows在裁剪時不能佔有它們。一旦頁面被鎖定,它們就不會被考慮成為用於工作集裁剪的可用記憶體的一部分。然而,只有SQL Server緩衝池分配才可以被鎖定,不過Windows仍然可以裁剪其他程序的工作集,這影響了SQL Server所依賴的資源。如果設定了合適的max server memory後你還繼續獲得工作集裁剪,或者SQL Server的工作集再次被裁剪的成本過於冒險,LPIM就應該被使。

如果LPIM在工作,你會在SQL Server的錯誤日誌中看到如下資訊:UsingLocked Pages in the Memory Manager。你可以閱讀有關Microsoft支援此功能,以及如何啟用它的內容,在http://support.microsoft.com/kb/2659143

優化Ad-Hoc Workloads

每次生成的執行計劃存放在計劃快取,以希望可以被重用,這是SQL Server管理工作負載的有效辦法之一。如果一個執行計劃將不會被重用,那麼它只是不必要地佔用資源,使用未引數化(unparameterized)的ad-hoc T-SQL是最有可能的原因。當您在SQL Server中執行程式碼,它會生成程式碼的雜湊值,並使用該值來決定計劃重用。如果你執行一個儲存過程,雜湊值會根據儲存過程名稱生成,計劃將在每個後續的過程呼叫中被重用,不管其所使用的引數值。

如果您執行儲存過程(ad-hoc T-SQL)之外的相同的程式碼,雜湊會對整個語句採用,包括任何文字值。當您改變文字值再次執行時,雜湊是不同的,因此SQL Server不能找到匹配的雜湊值,併產生一個新的執行計劃,而不是重用前一個。這種情況可能會導致一個場景稱為計劃快取膨脹(bloat),由此可能會產生成千上萬的ad-hoc計劃,並且快取了為1的usecount,即使程式碼基本上是相同的。理想的解決方案是使用儲存過程或函式,或引數化所有的ad-hoc T-SQL ,但是這可能是非常具有挑戰性的,而且往往無法實現,因為複雜性和公司策略。所以微軟在SQL Server 2008推出了伺服器級別選項Optimize for Ad-hoc Workloads來幫助解決這個問題。當啟用了此選項,則一塊ad-hoc T-SQL在首次被執行時,SQL Server將僅僅快取一個計劃存根,而不是完整的計劃。如果SQL Server隨後嘗試重用這個計劃,則計劃將再次產生,但這個時候是全部被快取。這就避免了這種場景,即數以千計的單次使用的計劃佔用了寶貴的快取空間。

如下圖,執行T-SQL語句得到所需結果,可以看到有超過3GB的記憶體用於快取,因此很有必要查清它的使用細節。

下面將通過Cached Object Type來破壞計劃快取的大小,你可以看到有718MB的計劃快取被ad-hoc計劃佔用,平均使用數是20,很低。

因此,現在你想確定其中有多少是單次使用(single-use)計劃,下圖表明有678MB的快取用於那些不被重用的計劃,它雖不是巨量,但它完全被浪費,因此沒有理由不清除這些計劃。

Optimize for Adhoc Workloads選項可確保這種情況下不會發生,因為它僅影響ad-hoc計劃我們建議在所有SQL Server的安裝中,預設開啟它