열 크기가 증가한 후 색인을 작성하는 데 시간이 더 걸리는 이유는 무엇입니까?


18

공급 업체는 전체 데이터베이스의 거의 모든 열에서 열 너비를 변경했습니다. 데이터베이스는 약 7TB, 9000+ 테이블입니다. 550 억 개의 행이있는 테이블에 인덱스를 작성하려고합니다. 공급 업체의 업그레이드 전에 2 시간 내에 색인을 만들 수있었습니다. 이제 며칠이 걸립니다. 그들이 한 것은 varchar (xx) 크기를 varchar (256)로 늘리는 것입니다. 따라서 대부분의 열은 varchar (18) 또는 varchar (75) 등이었습니다.

어쨌든 기본 키는 너비가 126자인 6 개의 열로 구성됩니다. 업그레이드 후 기본 키는 1283 자이며 SQL Server 제한 인 900자를 위반합니다. 전체 테이블 열 너비는 총 결합 varchar 수 1049에서 총 결합 varchar 수 4009로 증가했습니다.

데이터가 증가하지 않고 테이블이 모든 열 너비가 증가하기 전에 수행 된 것보다 더 많은 "공간"을 차지하지 않지만 색인이 불합리한 시간이 걸리는 것처럼 단순한 무언가를 작성하는 성능.

열의 크기를 늘리는 것이 유일한 일일 때 작성하고 색인을 작성하는 데 왜 그렇게 오래 걸리는지 설명 할 수 있습니까?

pk는 클러스터형 인덱스이므로 생성하려는 인덱스는 비 클러스터형입니다. 인덱스를 만들려고 여러 번 시도한 후에 포기했습니다. 나는 그것이 완료없이 4 ~ 5 일을 실행했다고 생각합니다.

파일 시스템 스냅 샷을 만들어 프로덕션 환경이 아닌 환경에서이 작업을 시도하고 더 조용한 서버에 데이터베이스를 가져 왔습니다.

답변:


12

Remus는 VARCHAR열의 최대 길이가 예상 행 크기에 영향을 미치므로 SQL Server가 제공하는 메모리 부여에 도움이된다고 지적했습니다 .

나는 그의 대답의 "이것에서 계단식으로"부분을 확장하기 위해 조금 더 많은 연구를 시도했습니다. 나는 완전하거나 간결한 설명이 없지만 여기에 내가 찾은 것이 있습니다.

재현 스크립트

내 컴퓨터에서 VARCHAR(256)버전 생성 시간이 약 10 배 정도 걸리는 가짜 데이터 세트를 생성 하는 전체 스크립트작성했습니다 . 사용 된 데이터가 정확하게 동일하지만, 제 테이블의 실제 최대 길이를 사용하여 18, 75, 9, 15, 123, 및 5모든 컬럼의 최대 길이를 사용하면서 256두 번째 테이블.


원래 테이블 키잉

여기에서 원래 쿼리가 약 20 초 안에 완료되고 논리적 읽기가 테이블 크기 ~1.5GB(195K 페이지, 페이지 당 8K) 와 동일하다는 것을 알 수 있습니다.

-- CPU time = 37674 ms,  elapsed time = 19206 ms.
-- Table 'testVarchar'. Scan count 9, logical reads 194490, physical reads 0
CREATE CLUSTERED INDEX IX_testVarchar
ON dbo.testVarchar (s1, s2, s3, s4)
WITH (MAXDOP = 8) -- Same as my global MAXDOP, but just being explicit
GO


VARCHAR (256) 테이블 키잉

를 들어 VARCHAR(256)테이블, 우리는 경과 시간이 크게 증가했다고 참조하십시오.

흥미롭게도 CPU 시간이나 논리적 읽기가 증가하지 않습니다. 이것은 테이블에 정확히 동일한 데이터가 있지만 경과 시간이 너무 느린 이유를 설명하지는 않습니다.

-- CPU time = 33212 ms,  elapsed time = 263134 ms.
-- Table 'testVarchar256'. Scan count 9, logical reads 194491
CREATE CLUSTERED INDEX IX_testVarchar256
ON dbo.testVarchar256 (s1, s2, s3, s4)
WITH (MAXDOP = 8) -- Same as my global MAXDOP, but just being explicit
GO


I / O 및 대기 통계 : 원래

우리가 조금 더 자세하게 ( p_perfMon, 내가 작성한 절차 사용) 캡처하면 대부분의 I / O가 LOG파일에서 수행되는 것을 볼 수 있습니다. 실제 ROWS(메인 데이터 파일)에서 I / O의 양이 상대적으로 적 으며 기본 대기 유형은 LATCH_EX인 메모리 페이지 경합을 나타냅니다.

우리는 또한, 내 회전 디스크 어딘가에 "나쁜"와 "놀랍게도 나쁜"사이 인 것을 알 수있다 폴 랜달에 따라 :)

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


I / O 및 대기 통계 : VARCHAR (256)

를 들어 VARCHAR(256)버전의 I / O 및 대기 통계는 완전히 다른 봐! 여기에서 데이터 파일 ( ROWS) 의 I / O가 크게 증가한 것을 알 수 있으며, 중단 시간으로 인해 Paul Randal은 단순히 "WOW!"라고 말합니다.

# 1 대기 유형이 이제는 놀라운 것은 아닙니다 IO_COMPLETION. 그러나 왜 이렇게 많은 I / O가 생성됩니까?

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


실제 쿼리 계획 : VARCHAR (256)

쿼리 계획에서 Sort운영자는 VARCHAR(256)쿼리 버전 에서 재귀 유출 (5 레벨 깊이!) 을 볼 수 있습니다. (원본 버전에서는 유출이 전혀 없습니다.)

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


실시간 쿼리 진행 : VARCHAR (256)

sys.dm_exec_query_profiles를 사용하여 SQL 2014+에서 실시간 쿼리 진행 상황을 볼있습니다 . 원래 버전에서, 전체 Table ScanSort모든 유출 (처리없이 spill_page_count남아 0걸쳐).

VARCHAR(256)그러나 버전 에서는 Sort운영자 에게 페이지 유출이 빠르게 누적되는 것을 볼 수 있습니다 . 다음은 쿼리가 완료되기 직전에 쿼리 진행률에 대한 스냅 샷입니다. 여기의 데이터는 모든 스레드에 걸쳐 집계됩니다.

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

각 스레드를 개별적으로 파는 경우 2 개의 스레드가 약 5 초 (테이블 스캔에 15 초를 소비 한 후 전체 20 초) 이내에 정렬을 완료합니다. 모든 스레드가이 비율로 진행되면 VARCHAR(256)인덱스 작성은 원래 테이블과 거의 같은 시간에 완료됩니다.

그러나 나머지 6 개의 스레드는 훨씬 느린 속도로 진행됩니다. 메모리가 할당되는 방식과 스레드가 데이터를 흘릴 때 I / O에 의해 유지되는 방식 때문일 수 있습니다. 그래도 확실하지 않습니다.

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


당신은 무엇을 할 수 있나요?

시도해 볼만한 것들이 많이 있습니다 :

  • 공급 업체와 협력하여 이전 버전으로 롤백하십시오. 이것이 가능하지 않은 경우,이 변경 사항에 만족하지 않는 공급 업체가 향후 릴리스에서 되돌릴 수 있도록하십시오.
  • 색인을 추가 할 때 현재 서버 수준 설정보다 낮은 숫자를 사용 OPTION (MAXDOP X)하는 X것이 좋습니다. OPTION (MAXDOP 2)내 컴퓨터 에서이 특정 데이터 세트를 사용 하면 VARCHAR(256)버전이 완료되었습니다 25 seconds(8 스레드와 3-4 분 비교)! 유출 동작이 더 높은 병렬 처리로 악화 될 수 있습니다.
  • 추가 하드웨어 투자가 필요할 경우 시스템에서 I / O (병목 가능성이 있음)를 프로파일 링하고 유출로 인한 I / O의 대기 시간을 줄이기 위해 SSD 사용을 고려하십시오.


추가 자료

Paul White는 관심이있을만한 SQL Server 내부 에 대한 멋진 블로그 게시물을 보유하고 있습니다. 병렬 정렬에 대한 스 필링, 스레드 왜곡 및 메모리 할당에 대해 조금 이야기합니다.


11

중간 정렬 테이블은 두 경우간에 다르게 추정됩니다. 이로 VARCHAR(256)인해 '이상적인'요청과 비교할 때 메모리 부여 요청 이 더 커지고 ( 더 커질) 실제 승인이 훨씬 적을 것입니다. 나는 이것이 정렬하는 동안 유출로 이어진다 고 생각합니다.

Geoff에서 스크립트 테스트 (100k 행에만 해당) 정렬 예상 행 크기 (141B 대 789B)의 차이를 분명히 볼 수 있습니다. 이것들에서 캐스케이드.


8
폴은 아마도 개발자 팀이 학습 자료로 사용할 콜 스택을 포함하여 더 철저하고 완전한 답변을 증명할 것이라고 확신합니다. 다시 ...
Remus Rusanu
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.