0

Binary(128) 列を持つテーブルがあります。Varbinary(128) ではなく Binary(128) を選択したため、128 バイトすべてが予約され、バイナリ値の更新時にページ分割が防止されます。テスト目的で、インデックスに 100 の FILLFACTOR があります。

列が Binary(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 データ型はメモリを予約するはずなので、この問題に遭遇しないと思いました。ストレージのインフレはどこから来ているのか?

ありがとう!

4

1 に答える 1

3

それはインフレではなく、むしろ動いているのかもしれません。binary(128) 列にクラスター化インデックスを作成したため、データは値に従って並べ替えられます。

値を更新すると、順序を維持するために、物理レコードを別のページに保存することが必要になる場合があります。他のページがいっぱいの場合は、分割する必要があります。

于 2013-02-25T21:40:39.753 に答える