Reputation: 2785
I have a table with a Binary(128) column. I chose Binary(128) over Varbinary(128) so it would reserve all 128 bytes and prevent page splits when updating the binary value. For testing purposes I have a FILLFACTOR of 100 on my index.
I found that even with the column set to a Binary(128) value it would still cause page splits when performing updates to this column.
Anyone have any idea why?
Here is some code to test with...
-- 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
If you perform a large update with the FILLFACTOR at 100 it causes severe fragmentation, but if I have the FILLFACTOR at 90 everything is good. I thought the non-var datatypes were supposed to reserve memory so you don't run into this issue. Where is the storage inflation coming from?
Thanks!
Upvotes: 0
Views: 306
Reputation: 35486
It may not be inflation, but rather moving. As you've made a clustered index on your binary(128) column, the data will be sorted according to the value.
As you update the value, the physical record may have to be stored on another page, to maintain the order. If that other page is full, it will have to be split.
Upvotes: 3