2013-02-25 5 views
0

У меня есть таблица с двоичным (128) столбцом. Я выбрал Binary (128) по Varbinary (128), поэтому он зарезервировал бы все 128 байт и предотвратил разбиение страниц при обновлении двоичного значения. В целях тестирования у меня есть FILLFACTOR из 100 по моему индексу.Сплит страницы, вызванный обновлением двоичной (128) Столбец

Я обнаружил, что даже при установке столбца в двоичное (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 datatypes должны были зарезервировать память, чтобы вы не столкнулись с этой проблемой. Откуда возникает инфляция хранения?

Спасибо!

ответ

3

Возможно, это не инфляция, а перемещение. Поскольку вы создали кластерный индекс в своем двоичном (128) столбце, данные будут отсортированы в соответствии со значением.

По мере обновления значения физическая запись может быть сохранена на другой странице для поддержания порядка. Если эта другая страница заполнена, ее нужно будет разделить.

+0

Продвижение, потому что это хороший звонок и абсолютно прав. Я удалил «Where tID% 10 = 0» из обновления и вместо этого обновил все записи. Это должно поддерживать порядок, правильно? Это все еще вызывает фрагментацию. –

+0

В конце концов, да, он будет поддерживать порядок. Однако, хотя это пакетная операция, каждая запись в конечном итоге должна обновляться один за другим на физическом уровне. После того, как каждая запись будет обновлена, она будет перемещена в нужное место. Таким образом, самой первой записи придется разбить страницу. Следующий, вероятно, перейдет на вновь разделенную страницу, но в итоге вы ударите еще одну полную страницу и получите еще один раздел. –

+0

Последний уточняющий вопрос, прежде чем я принимаю ответ. Если у меня не было столбца идентификатора и вместо него был Varchar в качестве первичного ключа/кластерного индекса, может ли изменение бинарных (128) записей вызвать изменение кластеризованного индекса, что может привести к разрыву страниц? Может ли изменение включенных табличных данных, связанных с кластеризованным индексом, вызвать это или, поскольку они все являются двоичными (128) значениями, должны ли новые данные отлично заменить старые данные? –