記憶體問題定位基本流程: 主要用到的性能計數器 Page life expectancy (資料庫計數器:主要顯示不被使用的頁,將在緩存中停留的秒數 ) Lazy writes/sec (資料庫計數器:惰性寫入器會在記憶體有壓力且有新的記憶體需求時觸發,成批的刷新“老化的緩衝區”) Page Reads/ ...
記憶體問題定位基本流程:
主要用到的性能計數器
- Page life expectancy (資料庫計數器:主要顯示不被使用的頁,將在緩存中停留的秒數 )
- Lazy writes/sec (資料庫計數器:惰性寫入器會在記憶體有壓力且有新的記憶體需求時觸發,成批的刷新“老化的緩衝區”)
- Page Reads/sec,Page Writes/sec (這裡使用資料庫級別計數器:當需要讀取或寫入的頁不在記憶體中,需要到磁碟中讀取時計數)
- Target Server Memory (KB) (SQL server能夠使用的記憶體總量)
- Total Server Memory (KB) (SQL SERVER使用的記憶體總量,這裡指BUFFER POOL的大小)
- Available MBytes (系統繫數器:主要顯示系統還有多少可用記憶體)
註:Target Server Memory (KB) - Total Server Memory (KB) 約等於SQL SERVER還可以使用的記憶體數。
步驟1.排除應用影響記憶體
Total Server Memory (KB)(SQL SERVER使用的記憶體總量,這裡指BUFFER POOL的大小)可以查看SQL Server使用的記憶體總量,如果當使用的記憶體總量很小,而伺服器依然有很大的記憶體Available MBytes請檢查,是否限制了SQL Server的記憶體使用。
Available MBytes 主要顯示系統中還多少空閑記憶體 (如果這個值較大,而Target Server Memory (KB) - Total Server Memory (KB) 為0或者較小,可以適當的調大max server memory(最大記憶體,稍後介紹))
如果Total Server Memory (KB) 計數器有陡降的情況發生,一般可以說明有外部程式對記憶體的使用占用的資料庫使用的記憶體。
步驟2.記憶體問題定位
記憶體持續壓力 Lazy writes/sec Page life expectancy 記憶體波動壓力
Page Reads/sec
Lazy writes/sec
Page life expectancy
步驟3.記憶體問題分析與解決(通用步驟)
系統設置最大記憶體max server memory
問:我系統記憶體本來就不夠為什麼還要設置使用上限?我這伺服器就給資料庫用還用設置?
答:資料庫是運行在windows 上的應用,他和notepad對於操作系統來說本質上沒區別,那麼這就好比君(操作系統)與 臣(資料庫)的關係。
而SQL SERVER是一個很喜歡記憶體的應用,所以很可能吃掉大量記憶體導致windows系統沒有足夠記憶體使用,,那麼這時候君臣關係就體現的淋漓盡致了,君(windows) 要臣(SQL SERVER)死(釋放記憶體)臣不得不死呀...這個釋放在一定程度上可不是單單讓windows夠用了,很可能導致SQL記憶體陡降,以致SQL 短時間假死(操作無響應)。所以為了你資料庫的穩定性,這個最大上限一定要設置。
記憶體設置推薦:
一般我比較推薦如果記憶體較小操作系統預留3G-4G ,如果記憶體大256或512以上在資料庫記憶體無壓力時預留5%給操作系統,剩下給SQL SERVER ,如果伺服器還有其他應用還要在SQL 中減掉應用所占的記憶體。
如果記憶體比較小且資料庫記憶體壓力大,則可以通過前面講述的Available MBytes 的判斷結果適量給系統預留記憶體。
註意:最大記憶體的設置單位為 MB。
語句的優化,讓語句消耗記憶體更少!
語句優化系列請關註後續文章,這裡只針對降低記憶體
降低記憶體對語句優化主要集中在幾個方面:
- 是否缺失索引?
- 消耗記憶體的操作是否可以消除(如排序)
- 降低語句複雜性,讓優化器能選用最佳計劃
語句消耗記憶體主要體現在大量的讀取,或者有排序等操作。
所謂的讀,簡單理解就是在語句執行時所需要用到的數據頁數,需要的越多就需要越大的記憶體來緩存這些數據頁。如果需要的頁不在記憶體中還需要從磁碟讀取 (磁碟讀取就是為什麼Page Reads/sec 會高)
簡單的一個加索引降低邏輯讀的例子~
語句使用了一個整個表掃描的計劃,執行了 19秒,邏輯讀取143800次,預讀137236 (磁碟上讀取),消耗了40KB 的記憶體 ,並且明確提示出缺少索引!
那麼我們加上提示缺少的索引,再次執行
加上索引的語句執行不到1秒 邏輯讀降低到13次,記憶體消耗已經可以忽略不計。這就是索引對語句的重要性!單條語句如此,你的系統中到底有多少這樣的語句呢?
再來看一個寫法修改的例子 :
只是簡單的改了下語句的寫法時間有7秒變成1秒,記憶體消耗從300+MB 變成 1MB
這兩個例子,告訴我們也許系統中簡簡單單做一些調整,記憶體的壓力就會明顯降低或者變得非常充足,所以在你下了一個需要購買記憶體的決定前,是否針對系統的語句進行過調優?
步驟4.記憶體問題分析與解決(特殊排查步驟)
記憶體波動
如果你是系統維護人員,看到類似這樣的記憶體數據指標,如果你還不能有一些思路,請你好好熟悉下你的系統。
這張圖很清晰地反映出系統每隔幾小時會有一次的記憶體壓力,那麼別忙著去找對應時間點的語句,我們最少要好好想一下,系統中有什麼操作定時執行?SQL JOB?計劃任務?前臺定時處理?等等等
這個規律的定時處理是否有異常?是否最近有什麼改動?執行的結果是不是和你想的一樣?
也許問題就這麼清晰的定位了......
-----------------------------------------------------------------------------------------------------
總結:記憶體對於資料庫來說是最為重要的依賴之一,記憶體的問題診斷和優化對系統至關重要。
優化語句可以讓你的系統記憶體壓力明顯降低。
語句優化所帶來的效果,在很大程度上會比添加硬體更有效!
作為一個技術人員對於系統問題的定位、分析、調優是最重要的。