행을 삭제할 때 비 클러스터형 인덱스가 더 많은 공간을 사용하는 이유는 무엇입니까?


22

75 억 개의 행과 5 개의 인덱스가있는 큰 테이블이 있습니다. 대략 1 천만 개의 행을 삭제하면 비 클러스터형 인덱스가 저장된 페이지 수를 늘리는 것으로 보입니다.

나는 dm_db_partition_stats페이지에서 차이를보고하기 위해에 대한 쿼리 를 작성했습니다.

dm_db_partition_stats 델타

인덱스 1 은 클러스터 된 인덱스이고 인덱스 2 는 기본 키입니다. 다른 것들은 클러스터되지 않고 고유하지 않습니다.

비 클러스터형 인덱스에서 페이지가 증가하는 이유는 무엇입니까?
나는 최악의 숫자가 동일하게 유지 될 것으로 예상했다.
삭제 중에 성능 카운터가 페이지 분할 증가를보고하는 것으로 나타났습니다.

삭제시 고스트 레코드가 다른 페이지로 이동해야합니까? 이것이 "유일 화기"와 관련이 있습니까?

우리는 RCSI를 출시하는 중이지만 지금은 RCSI가 꺼져 있습니다.

가용성 그룹의 기본 노드입니다. 어떻게 든 스냅 샷이 보조에서 사용된다는 것을 알고 있습니다. 그것이 관련이 있다면 놀랐습니다. 자세한 내용을 알아 보려면 dbcc 페이지 출력을 살펴보십시오. 누군가가 비슷한 것을 보길 바랍니다.


단지 질문-성장한 인덱스 중 하나에서 REORGANIZE를 실행하면 어떻게됩니까? 몇 페이지가 제거 되었습니까? 삭제하기 전에 재구성하면 어떻게됩니까? 내부 메커니즘으로 인해 새 페이지 전체를 할당하고 병합하는 것이 더 쉬울 수도 있지만 빈 페이지를 정리하지는 않는다고 생각합니다. REORGANIZE는 상대적으로 조각화되지 않았지만 더 큰 인덱스에서도 많은 양의 페이지를 삭제한다는 것을 알고 있습니다.
웃음 Vergil

좋은 질문 @LaughingVergil 대답이 있으면 여기로 돌아와서보고하겠습니다. (그러나 시간이 걸릴 수 있습니다).
Michael J Swart

우리의 경우, 이러한 증가는 일시적인 현상이었습니다. 충분한 인내심으로 고스트 정리는 결국 작업을 수행했으며 색인의 크기는 줄었습니다.
Michael J Swart

답변:


28

나를 매우 즐겁게하는 하나의 가능한 시나리오 :

  • 데이터베이스에 RCSI (Read Committed Snapshot), SI (Snapshot Isolation) 또는 AG (Availability Group)가 활성화되지 않은 경우 원래 행이 작성되었습니다.
  • RCSI 또는 SI가 사용 가능하거나 데이터베이스가 가용성 그룹에 추가되었습니다
  • 삭제 중에 RCSI / SI / AG 읽기를 지원하기 위해 삭제 된 행에 14 바이트 시간 소인이 추가되었습니다.

이 서버는 AG의 기본 서버이므로 보조 서버와 마찬가지로 영향을받습니다. 버전 정보는 기본에 추가됩니다. 데이터 페이지는 기본 및 보조에서 모두 동일합니다. 보조 저장소는 AG가 행을 업데이트하는 동안 버전 저장소를 사용하여 읽기를 수행하지만 보조 버전은 자체 타임 스탬프 버전을 페이지에 쓰지 않습니다. 그들은 단지 기본 작품에서 버전을 상속받습니다.

증가를 보여주기 위해 Stack Overflow 데이터베이스 내보내기 (RCSI가 활성화되지 않은)를 가져 와서 Posts 테이블에 많은 인덱스를 만들었습니다. sp_BlitzIndex @Mode = 2 (스프레드 시트에 복사 / 붙여 넣기 및 정보 밀도를 최대화하기 위해 약간 정리)로 인덱스 크기를 확인했습니다.

sp_BlitzIndex 전

그런 다음 행의 약 절반을 삭제했습니다.

BEGIN TRAN;
DELETE dbo.Posts WHERE Id % 2 = 0;
GO

흥미롭게도 삭제가 진행되는 동안 타임 스탬프를 수용 할 수 있도록 데이터 파일도 커졌습니다! SSMS 디스크 사용량 보고서에는 증가 이벤트가 표시됩니다.

성장 이벤트

삭제로 인해 데이터베이스가 커지는 데모를 좋아합니다. 삭제가 실행되는 동안 sp_BlitzIndex를 다시 실행했습니다. 클러스터형 인덱스는 행 수가 적지 만 크기는 이미 약 1.5GB 증가했습니다. AcceptedAnswerId의 비 클러스터형 인덱스는 급격히 증가했습니다. 대부분 null 인 작은 값에 대한 인덱스이므로 인덱스 크기가 거의 두 배가되었습니다!

삭제 중 sp_BlitzIndex

삭제가 완료 될 때까지 기다릴 필요가 없으므로 데모를 중단하겠습니다. 요점 : RCSI, SI 또는 AG를 사용하기 전에 구현 된 테이블에서 큰 삭제를 수행하면 클러스터를 포함한 인덱스가 실제로 버전 저장소 타임 스탬프의 추가를 수용하기 위해 커질 수 있습니다.


3
이것이 설명입니다. 14 버전 바이트가 누락 될 수있는 다른 상황이 있음이 밝혀졌습니다. 내 테스트에서 인덱스를 오프라인으로 다시 작성하면 버전 바이트없이 행을 다시 작성하는 것으로 보입니다.
Michael J Swart
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.