更新为二进制(128)列导致的页面拆分

时间:2013-02-25 21:35:33

标签: sql-server indexing sqldatatypes fillfactor

我有一个二进制(128)列的表。我在Varbinary(128)上选择了Binary(128),因此它会保留所有128个字节,并在更新二进制值时阻止页面拆分。出于测试目的,我的索引上有一个100的FILLFACTOR。

我发现即使将列设置为二进制(128)值,在执行此列的更新时仍会导致页面拆分。

任何人都知道为什么?

以下是一些要测试的代码......

--      Create working dataset
Create  Table   TestTable (tID Int Identity, TestBinary Binary(128));
Create  Clustered Index hmmmm On TestTable (TestBinary) With (FillFactor=100);

With    recur As
(   
        Select  Convert(Binary(128),0x01) As val, 1 As incr
        Union   All
        Select  Convert(Binary(128),incr + 0x01), incr + 1
        From    recur
        Where   incr < 100
)
Insert  TestTable (TestBinary)
Select  Convert(Binary(128),Convert(Int,r.val) + Convert(Int,r2.val) + Convert(Int,r3.val)) As TestBinary
From    recur r
Cross   Join    recur r2
Cross   Join    recur r3;

--      Rebuild Index as needed while testing
Alter   Index [hmmmm] On [dbo].[TestTable] Rebuild

--      Check index fragmentation
SELECT  Db_Name() As DatabaseName,
        o.id,
        s.name, 
        o.name, 
        page_count,
        record_count,
        index_type_desc,
        index_id,
        index_depth,
        index_level,
        avg_fragmentation_in_percent,
        fragment_count,
        avg_fragment_size_in_pages,
        avg_page_space_used_in_percent
From    sys.dm_db_index_physical_stats (DB_ID(), Object_ID('dbo.TestTable'), NULL , NULL, 'Detailed') n
Join    sysobjects o
        On  n.object_id = o.id
Join    sys.schemas s
        On  o.uid = s.schema_id;

--      Update the records
Update  t
Set     TestBinary = Convert(Binary(128),(Convert(Int,TestBinary) + 10000))
From    TestTable t

如果您在FILLFACTOR为100时执行大量更新,则会导致严重碎片,但如果我将FILLFACTOR设置为90,则一切都很好。我认为非var数据类型应该保留内存,所以你不会遇到这个问题。存储通胀来自何处?

谢谢!

1 个答案:

答案 0 :(得分:3)

这可能不是通货膨胀,而是移动。由于您在二进制(128)列上创建了聚簇索引,因此将根据值对数据进行排序。

在更新值时,可能必须将物理记录存储在另一页上,以维护订单。如果该其他页面已满,则必须将其拆分。