日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

SQL Server中一个隐性的IO性能杀手-Forwarded record

發布時間:2025/6/17 数据库 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SQL Server中一个隐性的IO性能杀手-Forwarded record 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

簡介

??? 最近在一個客戶那里注意到一個計數器很高(Forwarded Records/Sec),伴隨著間歇性的磁盤等待隊列的波動。本篇文章分享什么是forwarded record,并從原理上談一談為什么Forwarded record會造成額外的IO。

?

存放原理

??? 在SQL Server中,當數據是以堆的形式存放時,數據是無序的,所有非聚集索引的指針存放指向物理地址的RID。當數據行中的變長列增長使得原有頁無法容納下數據行時,數據將會移動到新的頁中,并在原位置留下一個指向新頁的指針,這么做的原因是由于使得當出現對Record的更新時,所有非聚集索引的指針不用變動。如圖1所示。

圖1.Forwarded Record示意

?

??? 這種由于數據更新,只在原有位置留下指針指向新數據頁存放位置行,就是所謂的Forwarded Record。

?

Forwarded Record如何影響IO性能?

??? 那么Forwarded Record既然是為了提升性能存在的機制,為什么又會引起性能問題?Forwarded Record的初衷是為了對堆表進行更新時,堆表上存儲位置的變化不會同時更新非聚集索引而產生開銷。但對于查找來說,無論是堆表上存在表掃描,還是用于書簽查找,都會成倍帶來額外的IO開銷,下面看一個例子。

CREATE TABLE dbo.HeapTest ( id INT, col1 VARCHAR(800) )

DECLARE @index INT
SET @index = 0
BEGIN TRAN
WHILE @index < 100000
BEGIN
INSERT INTO dbo.HeapTest
( id, col1 )
VALUES ( @index, NULL )
SET @index = @index + 1

END
COMMIT

代碼清單1.新建堆表并插入10萬條數據

?

?

??? 通過代碼清單1創建測試表,并循環插入10萬數據。此時我們來看該堆表所占用存儲的頁數,如圖2所示。

圖2.堆表空間占用

?

??? 此時對該表進行更新,讓原有行增長,產生Forwarded Record,此時再來看該堆表的存儲。如圖3所示。

圖3.產生8W+的forwarded record

?

??? 此時我們注意到,雖然數據僅僅占到590頁,但存在8W+的forwarded record,如果我們對該表進行掃描,則會看到雖然僅僅只有590頁,但需要8W+的邏輯IO,大大提升了對IO的開銷壓力,此外由于forwarded record頁與原頁往往不物理連續,因此對IOPS也存在挑戰。如圖4所示。

圖4.不該產生的額外IO開銷

?

??? 而上面查詢反映到性能計數器中,則呈現為如圖5所示的結果。

圖5.Forwarded Record計數器增長

?

如何解決

??? 看到Forwarded Record計數器,就說明數據庫中存在堆表,在OLTP系統中,所有的表上都應該有聚集索引。因此可以通過在表上增加聚集索引來解決該問題。

??? 通常來講,只有只寫不讀的表設置為堆表比較合適,但如果看到存在Forwarded Reocord,則說明堆表上存在讀操作,那么找到該堆表,找一個合適的維護窗口時間創建聚集索引則是比較理想的選擇。

??? 如果由于其他原因無法創建聚集索引,則可以對堆表進行表重建。

轉載于:https://www.cnblogs.com/CareySon/p/3829019.html

總結

以上是生活随笔為你收集整理的SQL Server中一个隐性的IO性能杀手-Forwarded record的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。