1. 程式人生 > >Expert 診斷優化系列------------------記憶體不夠用麼?

Expert 診斷優化系列------------------記憶體不夠用麼?

    現在很多使用者被資料庫的慢的問題所困擾,又苦於花錢請一個專業的DBA成本太高。軟體維護人員對資料庫的瞭解又不是那麼深入,所以導致問題遲遲不能解決,或只能暫時解決不能得到根治。開發人員解決資料問題基本又是搜遍百度各種方法嘗試個遍,可能錯過診斷問題的最佳時機又可能嘗試一堆方法最後無奈放棄。

    怎麼樣讓瑣事纏身的程式維護人員,用最快的方式解決資料庫出現的問題?怎麼讓我們程式設計師的痛苦降低到最小...每天喝喝茶水,看看新聞平安度過一天呢?本系列重要通過Expert for sqlserver 工具講解下資料庫遇到的各種問題的表象及導致這樣問題的根本原因,讓定位問題更準確,解決問題思路更清晰!!

    資料庫的效能好壞,對於終端使用者來說表現為點選的操作是否能夠快速響應,那麼反應到資料庫上就是語句執行時間是否夠短!

    對用運維人員資料庫效能的表現,簡單可能看成CPU 、記憶體、磁碟三巨頭指標是否正常,上一篇講述了CPU的基本診斷

    本篇我們就從記憶體下手,看看記憶體能夠看出哪些問題!

廢話不多說,直接開整-----------------------------------------------------------------------------------------

    首先說明一個誤區,你是否被這樣的畫面所震驚?

    

我的伺服器記憶體滿了,就是這個導致我資料庫慢!我的程式報錯也是因為這個,什麼都因為記憶體滿了!!  趕緊加記憶體吧~ 

    這個答案是大寫的 “不一定,SQL SERVER是一個很愛記憶體的傢伙,他會快取你的資料,執行計劃,連線資訊等等,所以出現這個現象是很正常的,不要輕易下結論,除非你經過仔細的研究和分析!

    那麼怎麼去分析到底是不是記憶體不足導致的問題呢?  下面我們來說說!

主要用到的效能計數器(不知道什麼是效能計數器的,請自行百度)

  1. Page life expectancy (資料庫計數器:主要顯示不被使用的頁,將在快取中停留的秒數 )
  2. Lazy writes/sec  (資料庫計數器:惰性寫入器會在記憶體有壓力且有新的記憶體需求時觸發,成批的重新整理“老化的緩衝區”)
  3. Page Reads/sec,Page Writes/sec  (這裡使用資料庫級別計數器:當需要讀取或寫入的頁不在記憶體中,需要到磁碟中讀取時計數)
  4. Target Server Memory (KB)  (SQL server能夠使用的記憶體總量)
  5. Total Server Memory (KB)  (SQL SERVER使用的記憶體總量,這裡指BUFFER POOL的大小)
  6. Available MBytes  (系統係數器:主要顯示系統還有多少可用記憶體)

  注:Target Server Memory (KB) - Total Server Memory (KB) 約等於SQL SERVER還可以使用的記憶體數

  Available MBytes 主要顯示系統中還多少空閒記憶體 (如果這個值較大,而SQL SERVER還可以使用的記憶體數為0或者較小,可以適當的調大max server memory(最大記憶體,稍後介紹))

    

   這裡不再細說這三個計數器,我們主要通過前三個計數的聯動來判斷系統的記憶體是否真的存在壓力!!!

   首先介紹一下,這三個計數器是如何聯動的?

   概念出發:Page life expectancy 不被使用的頁在快取中停留的秒數,如果低說明記憶體壓力

        Page Reads/sec 所要讀的資料不在記憶體中需要物理讀取

        Lazy writes/sec 記憶體壓力時成批的重新整理老化緩衝區 

   當一個操作需要大量讀取資料,且資料頁不在快取中 ——》 那麼需要大量從磁碟讀取冷資料放入快取(Page Reads/sec 升高) ——》快取有明顯壓力的時候Lazy writes/sec就會觸發(Lazy writes/sec升高),大批量的將老化的資料或快取計劃等刷出快取 ——》資料被清出快取,那麼頁生命週期就會下降(Page life expectancy)

    Page Reads/sec

    

    Lazy writes/sec

    

    Page life expectancy

    

    高能預警:當你看到自己的計數器是這個樣子的時候,你給的出結論不應該單單是,我記憶體有壓力!

    這個例子不光為了說明三計數器是聯動,而且也可以看出規律,那就是每三小時一次明顯的記憶體壓力。正如第一篇CPU文章的介紹,這種規律性的表象,作為系統的維護人員,一定要仔細想想什麼操作導致的問題?不要因為一個簡單的配置問題而拖慢了整個系統!

    我通過對問題時間點的語句分析發現,這個系統每三小時進行一次日誌備份,正常的日誌備份不會導致這樣的現象,但如果在日誌備份的時候加上CHECKDB呢?

    這就是所說的不要因為一個小的失誤而影響整個系統!

--------------------------------------------------------------------------------------------

系統記憶體不足的表象          

    下面展示一個記憶體壓力的伺服器這三個計數器的表象:

    Page Reads/sec

    

Lazy writes/sec    

    

    Page life expectancy 頁生命週期

    

    這幾個計數器反應出的問題絕對是系統記憶體嚴重不足,計數器雙高一低。那麼當我們知道系統記憶體不足的時候應該怎麼辦呢?加記憶體麼?

    不要急,下面我們說說如何讓你的系統節省記憶體,也許做過這一輪優化,你的系統記憶體就夠用了! 你沒聽錯,就是-----優化!

優化-----讓你的記憶體無壓力

    你要給你的系統設定最大記憶體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

語句的優化,讓語句消耗記憶體更少!

    語句優化系列請關注後續文章,這裡只針對降低記憶體

    降低記憶體對語句優化主要集中在幾個方面:

  1. 是否缺失索引? 
  2. 消耗記憶體的操作是否可以消除(如排序)
  3. 降低語句複雜性,讓優化器能選用最佳計劃

    語句消耗記憶體主要體現在大量的讀取,或者有排序等操作。限於篇幅這裡只做簡單的例子,詳細的語句優化請關注後續文章。

    所謂的讀,寫簡單理解就是在語句執行時所需要用到的資料頁數,需要的越多就需要越大的記憶體來快取這些資料頁。如果需要的頁不在記憶體中還需要從磁碟讀取 (磁碟讀取就是為什麼Page Reads/sec 會高

    

    簡單的一個加索引降低邏輯讀的例子~

    

    

    

    語句使用了一個整個表掃描的計劃,執行了 19秒,邏輯讀取143800次,預讀137236 (磁碟上讀取),消耗了40KB 的記憶體 ,並且明確提示出缺少索引!

    那麼我們加上提示缺少的索引,再次執行

    

    

    加上索引的語句執行不到1秒 邏輯讀降低到13次,記憶體消耗已經可以忽略不計。這就是索引對語句的重要性!單條語句如此,你的系統中到底有多少這樣的語句呢?

    再來看一個寫法修改的例子 :

    

    

    只是簡單的改了下語句的寫法時間有7秒變成1秒,記憶體消耗從300+MB 變成 1MB

    這兩個例子,告訴我們也許系統中簡簡單單做一些調整,記憶體的壓力就會明顯降低或者變得非常充足,所以在你下了一個需要購買記憶體的決定前,是否針對系統的語句進行過調優?

-----------------------------------------------------------------------------------------------------

 對於記憶體效能計數器的閥值簡單說明

 Page life expectancy 計數器這個時間要高於多少才算正常呢?

    答:很多資料上多這個值都有誤解,說是300S,300S是在十多年前的一個參考值,是基於當時的伺服器記憶體受到4GB記憶體的限制的影響得到的,

  目前伺服器記憶體動輒超過100GB的情況下,用同樣的標準,顯然是不夠準確的,這個值的計算是跟具體的伺服器記憶體配置有關的,一個可供參考的標準演算法是 Max Buffer Pool(GB)/4*300(S)

為什麼這裡缺少了一個 Buffer Cache hit ratio 計數器?

很多材料上都介紹其閾值是90%,95%之類的參考值,其實都是錯誤的,

    其實真正觀察過的人,早就會發現,從PLE和Buffer hit ratio得出根本不一致的結論。

詳細說明請參見:wy123的部落格

 -----------------------------------------------------------------------------------------------------

  總結:記憶體對於資料庫來說是最為重要的依賴之一,記憶體的問題診斷和優化對系統至關重要。

     優化語句可以讓你的系統記憶體壓力明顯降低。

     語句優化所帶來的效果,在很大程度上會比新增硬體更有效!

     作為一個技術人員對於系統問題的定位、分析、調優是最重要的,如果記憶體問題都通過加記憶體來解決,我們的價值何在呢?

 ----------------------------------------------------------------------------------------------------

注:此文章為原創,歡迎轉載,請在文章頁面明顯位置給出此文連結!
若您覺得這篇文章還不錯請點選下右下角的推薦,非常感謝!

  引用高大俠的一句話 :“拒絕SQL Server背鍋,從我做起!”

為了方便閱讀給出系列文章的導讀連結: