SQL Server에서 HEAP 조각화를 낮추는 방법은 무엇입니까?


10

최근에 하나의 힙 테이블에 70 % 이상의 조각화가 있음을 알았습니다. 그래서 나는하기로 결정

ALTER TABLE dbo.myTable REBUILD

충분히 웃긴 후에 20 % 조각화가 발생했습니다. 그 이후로 그 테이블에는 쓰지 않았습니다. 그래서 나는 한 번 더 재건을하기로 결정했습니다.

두 번째 시간이 지나면 테이블이 50 % 조각화를 더 많이합니다! 나는 이것이 어떻게 일어날 수 있는지 정말로 이해하지 못한다 ...


논리적 조각화를 말할 때 무엇을 의미합니까? 데이터 페이지 사용 측면에서 조각화입니다. 순서는 없지만 정렬되지 않은 데이터는 그 자체로 조각화되지 않습니다. 이 경우 조각화는 데이터 페이지를 효율적으로 사용함을 의미합니다.
tuxmania

2
테이블이 얼마나 큰지 물어봐야한다고 생각합니다. 행과 페이지에서.
Cody Konior

답변:


17

힙에서 조각화는 무엇을 의미합니까?

DMV avg_fragmentation_in_percent를 쿼리 하여 열에서 가져 오는 힙의 조각화 값은sys.dm_db_index_physical_stats

IN_ROW_DATA 할당 단위에서 인덱스의 논리적 조각화 또는 힙의 범위 조각화

또한 동일한 BOL은

힙의 리프 페이지에서 순서가 틀린 범위의 백분율입니다. 비 순차 범위는 힙에 대한 현재 페이지를 포함하는 범위가 이전 페이지를 포함하는 범위 다음에 실제로 다음 범위가 아닌 범위입니다.

따라서 힙에 할당 된 페이지에 여유 공간이 아니라 조각화를 생성하는 다양한 페이지 시퀀스가 ​​표시 됩니다.

이것은 작은 테스트로 증명할 수 있습니다. 힙 테이블을 작성하고 그 안에 레코드를 삽입 한 후 단편화를 점검하십시오.

create table dbo.HeapTest
(
Id INT not NULL Default (1),
Col1   char(5000) Not null Default ('Heaps Are Cool')
)

SET NOCOUNT ON

Insert into dbo.Heaptest default values
go 50

select index_type_desc,avg_fragmentation_in_percent,fragment_count,
avg_page_space_used_in_percent,record_count
from sys.dm_db_index_physical_stats(db_id(),object_id('dbo.HeapTest','U'),0,default,'detailed')

따라서 힙 테이블은 50 개의 레코드로 작성됩니다. 다음은 DMV sys.dm_db_index_physical 통계 쿼리 후의 조각화 모습입니다.

여기에 이미지 설명을 입력하십시오

avg_fragmentation_in_percent열 값이 33 %임을 알 수 있습니다 . 이제 페이지가 어떻게 배열되는지 봅시다. 문서화되지 않은 쿼리 를 사용하여 수행 할 수 있습니다 %%lockres%%. 쿼리는

SELECT  %%lockres%%, * FROM dbo.HeapTest;

아래는 출력 결과입니다. 관련 부분 만 첨부합니다. dbo.HeapTest 테이블에 50 개의 행을 삽입 한 이후 쿼리에서 50 개의 행을 생성했습니다.

여기에 이미지 설명을 입력하십시오

무엇 말하는 것은 첫 번째 페이지입니다 것은 ID를 가지고 197다음 페이지하는 ID가 242우리가 페이지 ID에 도달 할 때까지 다음 페이지 것은 연속 ID를 가지고 264우리가 페이지 ID를 가져 그 후 때문에 280. 이 그래서 점프 페이지의 ID 번호에 실제로 분열을 일으키는 것입니다.

이제 힙을 다시 빌드하지 말고 조각화 및 페이지 배열 방법을 보려면 명령을 다시 실행하십시오. 우리는 조각화를 얻는다

여기에 이미지 설명을 입력하십시오

조각화는 이제 볼 수 있습니다 14%.

할당 된 페이지 번호를 보자

여기에 이미지 설명을 입력하십시오

우리는이 하나 개의 점프는 모든 페이지가 연속적으로 페이지 ID를 할당 휴식. 단 하나의 점프 조각화가 상당히 감소했기 때문입니다.

힙을 다시 빌드하고 조각화를 확인하면 완전히 사라졌습니다. 그리고 페이지 ID 할당은

여기에 이미지 설명을 입력하십시오

조각화가 증가한 이유

이제 조각화를 일으킨 원인에 대해 페이지가 힙에 할당 될 때 페이지가 할당되지 않은 이유는 페이지에 할당 된 PAGE ID의 급상승이 조각화 값을 증가시키는 원인으로 보아 왔기 때문입니다.

HEAP의 단편화라는 단어에는 의미가 없으며 순서가없는 여러 페이지에 대해 단편화를 어떻게 정의 할 것인지도 명심해야합니다.

조각화에 대해 정말로 걱정

힙 테이블이 조각화되고 쿼리 속도가 느려지는 시나리오에 실제로 직면하면 테이블을 재구성하는 것보다 클러스터 된 인덱스를 만드는 것이 좋습니다. 그 이유는 힙을 재 구축 할 때 모든 기본 비 클러스터형 색인도 재 구축되므로 많은 자원을 사용하고 트랜잭션 로그를 크게 사용하여 재 구축 프로세스에 시간이 훨씬 오래 걸리기 때문입니다. 프로덕션 시스템에서는 항상 이것을 피하려고 시도합니다. 바울은 이것을 신화 섹션에서 힙에 대해 다루었 다 .

추신 : 프로덕션 시스템에서는 문서화되지 않은 명령을 사용하지 마십시오. 이것은 단지 시연을위한 것입니다.


자세한 분석에 감사드립니다. 일부 데이터 저장소 애호가는 클러스터 인덱스를 사용하는 것보다 낫다고 생각하기 때문에 큰 힙 테이블에 직면하고 있지만 힙에서 많은 검사 제약 조건과 클러스터되지 않은 인덱스를 사용 하므로이 상황에서 힙의 이점을 실제로 보지 못합니다. 그러나 나는 바보 같은 개발자이기 때문에 이것을 처리해야합니다. 통찰력에 다시 한번 감사드립니다 :)
tuxmania

select index_type_desc, avg_fragmentation_in_percent, fragment_count, avg_page_space_used_in_percent, record_count from sys.dm_db_index_physical_stats (db_id (), object_id ( 'dbo.HeapTest', 'U'), 0, default, '에서 결과 만 반환)'를 어떻게 실행합니까? 하나의 테이블? 'object_id'에 내 테이블 이름을 올바르게 지정하더라도 모든 테이블의 모든 인덱스에서 반환됩니다.
Mickael

@Mickael 현재 데이터베이스를 가져 오는 db_id () 함수를 사용했으며 특히 객체 이름을 지정 했으므로 항상 현재 데이터베이스를 찾아보고 Heaptest결과를 제공합니다. 당신이 뭔가를 놓친 것 같습니다. 이 경우 호환성 수준이 80이 아닌지 확인하십시오. db_id 함수가 작동하지 않습니다
Shanky

@Shanky 프로덕션 환경에서 문서화되지 않은 쿼리 %% lockres %%를 사용하지 않는 것이 좋습니다. 자세히 설명해 주시겠습니까?
Ralph

@ user1624552 문서화되지 않았기 때문에 MS는 해당 문서에 대한 문서도 업데이트하지 않습니다. 그 효과가 어떻게 작동하는지 그 후유증은 무엇인지 문서화되지 않았으므로 그렇게 요구됩니다. 예를 들어 숨겨진 스케줄러 를 만드는 fn_dump_dblog () 명령이 있으며 이는 좋지 않습니다. 이 명령도 지원되지 않습니다. 당신은 그것을 사용할 수 있지만 위험은 당신에게 있습니다.
Shanky
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.