SQLSERVER解決HOT PAGE問題的其中一個思路使用表分區
什麼叫HOT PAGE?
應用程式發來大量的並發語句在修改或者插入同一張表格裡的記錄,而表格架構設計以及使用者商務邏輯使得這些修改跟插入都集中在同一個資料頁面,
或者數量不多的幾個資料頁面上。這些頁面有時候也被稱為 hot page 熱力頁。這樣的瓶頸通常只會發生在並發使用者比較多的、典型的OLTP系統上。
介紹一下PAGELATCH:
簡單來講,當SQLSERVER把資料讀取到記憶體之後,資料以“頁”為單位存放的,假如有兩個使用者同時修改或者插入的資料都在同一個頁面,那麼,
SQLSERVER會在頁面上放一個PAGELATCH(輕量級的)鎖,這些鎖跟意圖共用鎖、獨佔鎖定、行鎖、鍵鎖不同,這些LATCH鎖只存在於記憶體裡
當A使用者要修改資料頁編號為100這個頁面時,SQLSERVER就會在100這個頁面加上一個PAGELATCH鎖,以防止其他使用者同時修改這個頁面
以得到一個修改的先後順序,當A使用者修改完畢以後,PAGELATCH就會釋放,以供B使用者修改。
一般使用下面的SQL語句的wait_type列就可以看到當前哪個會話需要等待獲得PAGELATCH鎖
1 SELECT * FROM sys.[dm_exec_requests]
HOTPAGE介紹完了,PAGELATCH介紹完了,那麼這個HOTPAGE帶來的瓶頸以及危害大家應該知道了吧?
不知道?好吧,跟大家說一下:
如果大量並發使用者同時訪問同一個資料頁面,那麼SQLSERVER就要對這個資料頁面的PAGELATCH進行申請釋放,
不斷申請和釋放,如果SQLSERVER處理使用者的插入或者修改請求比較慢的話,那麼就會造成“阻塞”。
一般HOTPAGE會在以下情況發生:
例如:有一個股票交易系統,每一筆交易都會有一個流水號是遞增而且不可重複的而客戶發過來的交易請求,
都要儲存在同一張交易表裡。每一個新的交易,都要插入一條新記錄。如果設計者選擇在流水號上建叢集索引(這也是很自然的)
就容易遇到HOT PAGE的PAGE LATCH資源瓶頸。在同一時間,只能有一個使用者插入一筆交易
怎樣才能緩解這種瓶頸呢?
(1)最簡單的方法:換一個資料列建叢集索引,而不要建立在IDENTITY欄位(例如上面的交易流水號)上。
這樣表格裡的資料就按照其他方式排序,同一時間的插入就有機會分散在不同的頁面上
(2)如果實在是一定要在IDENTITY的欄位上建立叢集索引,建議根據其他某個資料列在表格上建立若干個分區(Partition)表分區,
把一個表格分成若干個分區,可以使得接受新資料的頁面數目增加
例如:
以上面的那個股票交易系統為例子。不同的股票屬於不同的行業。開發人員可以根據股票的行業屬性,將一張交易表分成若干個分區。
在SQLSERVER裡,資料分割資料表(Partition Table) 的每個分區都是一個獨立的儲存單位。分屬不同分區的資料行是嚴格分開儲存的。
所以,同一個時間發生的交易記錄,因其他行業不同,也會分別儲存在不同的分區裡。這樣,在同一個時間點,可以插入不同行業的
交易記錄。每個分區上的HOT PAGE(接受新資料插入的PAGE)就不那麼HOT了
所以,在自增列上建立叢集索引要看情況,不然會很容易遇到HOTPAGE噢 o(∩_∩)o
2012-12-27補充
在這裡再說一下,分區是把雙刃劍,如果分區了的話,會帶來掃描次數的增多
原本表沒有分區的,那麼掃描一次就可以了,現在比如分了2個區,那麼就要
掃描2次,每個分區需要2次I/O,那麼如果資料在分區2裡面的話,就需要
4次I/O