一.概述
在前幾章介紹過 sql server 性能調優資源等待之PAGEIOLATCH,PAGEIOLATCH是出現在sql server要和磁盤作交互的時候,所以加個IO兩個字。這次來介紹PAGELATCH。PAGELATCH類型是sqlserver在緩沖池里的數據頁面上經常加的另一類latch鎖。
既然緩沖池里的數據頁面與PAGELATCH有關系,那先來介紹數據頁面。
1. 數據頁面
數據頁面在"sql server 索引闡述系列二 索引存儲結構"中有詳細介紹,這里講與PAGELATCH有關的知識點。 一個頁面包含頁頭,數據存儲,頁尾偏移量。 在頁頭里包含了頁面屬性,頁面編號,記錄了當前頁面空閑的起始位置,當sqlserver 在要插入的時候,就能夠很快地找到插入的位置,而頁尾的偏移量記錄了每一條數據行所有頁中的位置,當需要查找頁中數據時,通過頁尾的偏移量很快能定位。
當數據行發生變化時, sql server不但要去修改數據本身,還要維護頁中數據行與偏移量的關系。
2. PAGELATCH
講了這么多關於數據頁面, 現在來理清一下關系, lock鎖是保證數據頁中數據的邏輯關系,PAGEIOLATCH的latch鎖是保證數據頁與磁盤進行存儲的關系, PAGELATCH的latch鎖是保證數據頁中數據行與頁尾的偏移量的關系。當然這種區別介紹是為了更好的去理解它們之間的關系,PAGELATCH作用並不只是這點, 它還會維護系統頁面如SGAM,PFS,GAM頁面等。
3. HotPage現象
當我們為一個表創建主鍵自增ID時, 那么sql server將按照ID字段的值順序進行存儲,在大並發下,為了保證ID值按順序存放在數據頁中,這時PAGELATCH就會latch鎖住數據頁面里的存儲結構, 使ID值排隊保持先后順序 。測試Hotpage現象可以是程序后端並發插入或使用 SQLIOSim工具來並發測試。
下面來看一個簡單的圖:當前表里有一個page 100的頁面, 該頁中已有二行數據(rid1和rid2) 分別對應着頁尾的偏移量1和2。 這時有二個插入任務,同時插入到page100頁,假設第一個任務申請到了ex_latch鎖,第二個任務就會等待,使數據行和偏移量對一 一對應。
由於數據頁的改動都是在內存中完成的,所以每次修改時間都應該非常短,幾乎可以忽略。如果該資源成為了sql server等待的瓶頸有以下幾種情況:
(1) sql server 沒有的明顯的內存和磁盤瓶頸。
(2) 大量的並發集中在表里的一個數據頁上叫hotpage
(3) tempdb 臨時表也可以會成為瓶頸,通常可以通過增加tempdb文件來緩解。 具體查看Tempdb怎么會成為性能瓶頸?。
4. 查看PAGELATCH現象
4.1 通過sys.dm_exec_query_stats來查看實例級別的等待
select wait_type, waiting_tasks_count, wait_time_ms , max_wait_time_ms, signal_wait_time_ms from sys.dm_os_wait_stats where wait_type like 'pagelatch%' order by wait_time_ms desc
在實例級別中等待次數最多的是PAGELATCH_EX的latch 排它鎖, 平均每次耗時90毫秒,這個平均值應該是不會有性能問題。
4.2 能過sys.dm_exec_requests 來實時查看sql語句級, 可以采用不定時監聽能過session_id來獲取sql 語句所對應的表,以及等待的數據頁類型 。
SELECT * FROM sys.dm_exec_requests WHERE wait_type LIKE 'pagelatch%'
5. 解決思路
(1) 通過設計表結構,使hotpage現象由單面的並發訪問,分散到多個頁面。
(2) 如果是在identity字段上有瓶頸, 可以創建多個分區,因為每個分區都有自己的存儲單位,這樣hot 單頁現象就分散了。