天天看點

SQL Server 存儲引擎-剖析Forwarded Records

我們都知道資料在存儲引擎中是以頁的形式組織的,但資料頁在不同的組織形式中其中對應的資料行存儲是不盡相同的,這裡通過執行個體為大家介紹下堆表的中特有的一種情形Forwared Records及處理方式.

概念

堆表中,當對其中的記錄進行更新時,如果目前資料頁無法滿足更新行的容量,此時這行記錄将會轉移到新的資料頁中,而原資料頁中将會留下指針(檔案号,頁号,槽号)連結到新的資料頁中.

Code 建立測試資料

Code 檢視相關資料頁 如圖1-1

                                                              圖1-1

現在我們來更新ID=3的資料使目前資料頁(79)無法容納此行資料,然後觀察資料頁,

Code

update dbo.testtb set str2=replicate('t', 1000) where ID=3--update ID=3

GO

DBCC PAGE('testpage', 1, 79, 3)

繼續找到slot 2槽位(ID=3)觀察 如圖1-2所示,此時slot2資料的Record Type = FORWARDING_STUB,也就是此時槽位2隻留下RID記錄,資料轉到其他資料頁中了(Forwarding to  =  file 1 page 94 slot 0  )

                                                圖1-2

這裡稍微深入的講下RID的存儲内容,執行個體中根據dbcc page已經給我們展示RID的内容,實際上存儲是16進制的如圖1-2中的黑色部分(045e0000 00010000 00

).具體對應RID内容如圖1-3

                                            圖1-3

我們在找到實際存儲ID=3的資料頁看下資料内容(1:94:0) 如圖1-4

圖中我省去了資料内容

code

DBCC PAGE('testpage', 1, 94, 3)

                                         圖1-4

接下來我們繼續更新ID=3讓新的資料頁也無法容納它,然後觀察相應的資料頁如圖1-5(三個dbcc page 合成圖)

(此時ID=3的原始頁94,槽号2指向了新的資料頁位置184)如圖所示1-5所示

                                               圖1-5

可以看出id=3的原始頁(1:79:2)的資料再次變更後的由(1:94:0)挪到了(1:184:2)中,

而頁号94槽号0就不存在了.

堆表中的非聚集索引.

當堆表中有非聚集索引存在時,非聚集索引RID指向的原始頁位置

我們通過執行個體看下

注:關于heap rid我就不做詳細介紹了,執行個體中通過查詢轉換可以算出10進制對應的RID

可以看到select 的輸出正好是(1:79:2)我們原始的id=3的位置

關于性能

由于forwarded record的存在,當通路到這種資料行時,會消耗額外的随機IO,進而影響性能.更有甚者,由于額外的資料頁被放入記憶體中,造成BP的污染,緻使性能下降.

(研發要求對一個頻繁通路的大堆表更新擴充欄位,執行完了性能依舊下降有木有?)

我們通過簡單執行個體來看下

通路forwarded record會造成額外IO如圖2-1

                                    圖2-1

當表資料量大時,大批量更新擴充欄位會造成對緩沖池的污染

順序執行代碼時可以看出,testpage表更改前後占Buffer Pool的大小分别為15M,31M,對BP影響明顯.

監控/發現

實際生産環境中我們需要監控一些性能名額用來輔助DBA解決問題,保證運維效率,針對這裡,我們監控性能計數器中SQL Server Access Methods對象中的forwarded records/sec,如果你設定的了性能Baseline,這個值如果有異常變化,則需要我們關注.

同時我們也可以根據系統的DMF找出特定對象的forwarded records資訊.代碼如下

注:可以通過簡單的Batch檢索整個庫甚至執行個體中的堆表的相關資訊,有興趣的朋友自己寫下.

處理

如果發現了因為forwarded Recordes引起的性能問題,我們可以選擇表中建立聚集索引改變資料組織結構(forwarded Recordes隻在堆表中存在).如果無法添加聚集索引,也可以選擇重組堆表(alter table heap rebuild)操作時應注意時間視窗

結語

任何事物都存在因果,套用資料庫系統中,我們應該清楚自己的所作所為,以及帶來的效用/影響.合理到位的分析,評估會讓我們的工作變得從容.