SQL SERVER——TempDB問題查找定位與解決

步驟1.TempDB壓力診斷

等待類型診斷

TempDB的爭用壓力在等待篇中已經簡單介紹,等待的表現爲 pagelatch_類等待,等待的資源是 “2: X :X ”

 

 

tempDB所在磁盤的響應時間

 

一個實例下只有一個tempdb,也就是當你在一個實例下創建了100個數據庫,這100個數據庫也只能用這一個TempDB。

你創建的臨時表,或SQL執行語句所需要的排序等操作都需要用到Tempdb。所以TempDB對磁盤的響應時間要求比較高。

步驟2.解決問題

 

把TempDB設置成多個來分攤這個壓力。

分成多個文件

    作爲一般規則,如果邏輯處理器數小於或等於 8,使用和邏輯處理器相同數量的數據文件。如果邏輯處理器數大於 8 時,使用 8 個數據文件,然後如果仍然存在爭用,增加數據文件數4 的倍數(最多的邏輯處理器數)直到爭用降低到可接受的程度或對工作負荷/代碼進行更改。

文件大小、增長率要相同

   這裏需要注意一個小細節,你所分配的文件必須大小一致,如果設置自動增長那麼增長率要相同

    

 

 

 

TempDB磁盤劃分

    大多數情況下,TempDB的文件不需要拆分磁盤,在同一個磁盤即可,如果壓力大可以選擇放置在一個單獨的磁盤中,這樣不會與其他文件(如數據讀寫)發生磁盤資源競爭。

    

 

    如果出現TempDB 讀取響應時間高的情況,請考慮,TempDB的磁盤相關優化,如將TempDB文件單獨放入比較快的磁盤。

 

 

步驟3.語句調優

  語句調優篇提到語句中使用臨時表或表變等會減少語句的複雜度,提升語句的效率,是常用的三板斧之一,但這裏的需要一個平衡。如果對語句過度使用會造成文中提到的TempDB壓力。那麼怎麼樣平衡呢?下面給出幾點建議:

  1. 切記不要過度使用臨時表!臨時表的使用主要有兩個場景,拆分語句降低複雜性。另一個是緩存中間結果避免重複操作。
  2. 減少使用臨時表鎖系統表的時間!”select 字段 into #臨時表 from“ 如果語句執行時間過長這將是災難,儘量選用先創建,後插入的做法。
 
 
 

原理:TempDB壓力從哪來?

    當數據庫創建一張新表的時候,SQL Server要爲這張表分配存儲頁面,同時SQL Server也要修改SGAM, PFS, 和GAM頁面,把已經分配出去的頁面標誌成已使用。所以每創建一張新表,SGAM, PFS, 和GAM這些系統頁面都會有修改動作。這種行爲對一般的用戶數據庫不會有問題,因爲正常的應用不會折騰着不停地建表、刪表。但是tempdb就不同了。如果一個存儲過程使用了臨時表,而這個存儲過程被併發用戶廣泛使用,那很自然地就會有很多併發用戶在tempdb裏同時創建表,做完了以後又刪除表。這樣,在一個時間點,會有很多任務要修改SGAM, PFS, 或GAM頁面。但是爲了維護物理的一致性,對於同一個頁面,SQL Server在一個時間點同時只允許一個用戶修改它。所以對於tempdb,如果同時有很多很多人要在同一個數據文件裏分配空間,那這個數據文件的SGAM, PFS, 或GAM頁面,就有可能成爲系統瓶頸。大家只能一個一個做,併發度上不去。

    這就好像你進停車場要登記交費一樣!一個一個來不要急~

    

 

    等待資源爲 : “2:1:3” 這是什麼意思? ID 爲 2 的數據庫(TempDB)的 1號文件 的 頁碼爲3的頁(SGAM頁面)!

 

    

 

 

    這裏關於系統頁不過多的介紹,想詳細瞭解的朋友請參見 :  SQL Server中的GAM頁和SGAM頁

 

我創建個臨時表跟系統頁還有關係?

    下面也用一個例子說明 : 

    創建臨時表的時候會對系統表中進行插入和更新,而刪除臨時表逆向過程會刪除或更新系統表!

 
use [AdventureWorks2012]
GO
checkpoint
go
create table #t
(
id int
)
drop table #t


use tempdb
go
select Operation,CONTEXT,[Transaction ID],AllocUnitId,AllocUnitName,[Page ID],[Transaction Name],Description from fn_dblog(null,null)

 

 

    

    

 

 

    所以當你併發過高且頻繁創建刪除臨時表的時候就會造成大量的爭用。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章