2013-02-25 2 views
0

이진 (128) 열이있는 테이블이 있습니다. Varbinary (128)에 비해 Binary (128)를 선택하여 128 바이트를 모두 예약하고 이진 값을 업데이트 할 때 페이지 분할을 방지합니다. 테스트 목적으로 필자의 인덱스에는 100 개의 FILLFACTOR가 있습니다.페이지 분할 이진 (128) 열로 인해 발생했습니다

이진 (128) 값으로 설정된 열의 경우에도이 열을 업데이트 할 때 페이지 분할이 여전히 발생한다는 것을 알게되었습니다.

누구나 이유가 무엇입니까? 당신이 심각한 분열의 원인 (100)에 FILLFACTOR와 함께 큰 업데이트를 수행 할 경우 다음

--  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 

... 함께 테스트하는 몇 가지 코드입니다,하지만 난 경우 90 모두의 FILLFACTOR이 좋다. 비 var 데이터 유형이 메모리를 예약하기로되어 있으므로이 문제에 부딪치지 않는다고 생각했습니다. 스토리지 인플레이션은 어디에서 발생합니까?

감사합니다.

답변

3

인플레이션이 아니라 오히려 움직이는 것일 수도 있습니다. 이진 (128) 열에서 클러스터 된 인덱스를 만들었으므로 데이터는 값에 따라 정렬됩니다.

값을 업데이트 할 때 순서를 유지하기 위해 실제 레코드를 다른 페이지에 저장해야 할 수 있습니다. 그 다른 페이지가 꽉 차 있다면, 그것은 나눠 져야합니다.

+0

이것은 좋은 호칭이므로 절대적으로 사실입니다. 업데이트에서 "Where tID % 10 = 0"을 제거하고 대신 모든 레코드를 업데이트했습니다. 이 명령을 유지해야합니다, 맞습니까? 여전히 조각화가 발생합니다. –

+0

결국, 네, 명령을 유지할 것입니다. 그러나 일괄 작업 인 동안 각 레코드는 결국 물리적 레벨에서 하나씩 업데이트해야합니다. 각 레코드가 업데이트되면 올바른 위치로 이동됩니다. 따라서 첫 번째 레코드는 페이지를 분할해야합니다. 다음 페이지는 새로 분할 된 페이지로 이동하지만 결국에는 다른 페이지 전체를 클릭하여 다른 페이지 분할로 끝납니다. –

+0

답변을 수락하기 전에 마지막으로 명확한 질문입니다. ID 열이없고 대신 기본 키/클러스터 된 인덱스로 Varchar가있는 경우 이진 (128) 레코드를 변경하면 페이지가 분할 될 수있는 클러스터 된 인덱스가 변경 될 수 있습니까? 클러스터 된 인덱스와 관련된 테이블 데이터를 변경하면이 문제가 발생합니까 아니면 새 데이터가 이전 데이터를 완벽하게 대체해야하는지 모두 Binary (128) 값이 되었기 때문에? –