程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> SqlServer數據庫 >> 關於SqlServer >> Forwarded record:SQL Server中一個隱性的IO性能殺手

Forwarded record:SQL Server中一個隱性的IO性能殺手

編輯:關於SqlServer

簡介

最近在一個客戶那裡注意到一個計數器很高(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開銷,下面看一個例子。

CREATETABLEdbo.HeapTest ( id INT, col1 VARCHAR(800) )
    
DECLARE@indexINT
SET@index= 0
BEGINTRAN
WHILE @index< 100000 
    BEGIN
        INSERT  INTOdbo.HeapTest
                ( id, col1 )
        VALUES  ( @index, NULL)
        SET@index= @index+ 1

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

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

圖2.堆表空間占用

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

圖3.產生8W+的forwarded record

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved