페이지 압축을 사용할 때 행 오버 헤드는 무엇입니까?


10

650 숫자 (19,4) 열이있는 테이블을 만들었습니다. 페이지 압축을 켤 때

ALTER TABLE fct.MyTable REBUILD  WITH (DATA_COMPRESSION = PAGE);

나는 얻다

메시지 1975, 수준 16, 상태 1
인덱스 'PK_Mytable'행 길이가 최대 허용 길이 인 '8060'바이트를 초과합니다.

그러나 650 곱하기 9 바이트는 5850 바이트에 불과하며, 이는 명시된 제한 8060 바이트와는 거리가 멀습니다.

서버에서 SQL Server 2016 SP1 CU2와 함께 Windows 2012 r2를 실행 중

페이지 압축을 사용할 때 행 오버 헤드는 무엇입니까?

다음은 내가 의미하는 바를 보여주는 코드입니다.

/* test script to demo MSG 1975 */
DECLARE @sql NVARCHAR(max)='', @i INT =0
drop table if exists dbo.mytable;

SET @sql = 'Create table dbo.Mytable (MyTableID bigint not null 
  identity(1,1) primary key clustered, '

WHILE @i < 593 BEGIN
    SET @sql += ' Column' + LTRIM(@i) + ' numeric(19,4) null, '
    SET @i +=1
END

SET @sql += ' LastColumn int) '
--SET @sql += ' with (DATA_COMPRESSION = ROW) '
SET @sql += ' with (DATA_COMPRESSION = PAGE) '

SELECT @sql
EXEC sys.sp_executesql @sql

SELECT top 10000 * FROM dbo.MyTable MT

행 압축도 실패하지만 다른 행 수에 있습니다.


기본 키는 얼마나 큽니까? 이것이 사실 테이블이고 성능을 압축하고 향상시키려는 경우 columnstore 인덱스를 읽으면 큰 영향을 줄 수 있습니다. 페이지 압축 오버 헤드는 CPU 사용량을 더 많이 압축 해제하는 것입니다.
Stijn Wynants

@StijnWynants; BigInts에는 8 바이트가 사용됩니다. 이것은 실제로 사실이지만 열 저장소 인덱스를 보증하기에 충분한 행이 들어오지 않습니다.
Henrik Staun Poulsen

답변:


13

클러스터 된 PK 제약 조건없이 테이블을 만들려고하면 약간 다른 오류가 발생합니다.

메시지 1701, 수준 16, 상태 1, 줄 1 최소 행 크기가 1,053 바이트의 내부 오버 헤드를 포함하여 8067이므로 테이블 'Mytable'을 만들거나 변경하지 못했습니다. 허용 가능한 최대 테이블 행 크기 인 8060 바이트를 초과합니다.

이 오류 메시지에서 페이지 압축에 1530 바이트의 내부 오버 헤드가 있음을 알 수 있습니다.

이제 수학을 할 수 있습니다 :

  • bigintMyTableID의 경우 8 바이트
  • intLastColumn의 경우 4 바이트
  • 593 개 numeric(19,4)열 각각에 대해 9 바이트 (총 5337 바이트)
  • 1530 바이트의 압축 오버 헤드

따라서 8 + 4 + (593 * 9) + 1530 = 6879. 잠깐만 .. 아직도 8060 이하입니다. 무슨 일입니까?!


페이지 압축 알고리즘은 실제로 여러 압축 알고리즘을 함께 쌓습니다. 첫 번째 단계는 ROW 압축을 적용하는 것입니다. 행 압축 오버 헤드는 해당 오류 메시지에 나열된 1530 바이트의 오버 헤드에 포함되지 않습니다.

내 블로그BOL에서 행 압축이 작동하는 방식에 대해 자세히 읽을 수 있습니다 . BOL 기사에서는 numeric스토리지를 "이 스토리지는 VarDecimal 스토리지 형식과 정확히 동일하지만"이라고 설명하지만 설명하지는 않습니다 vardecimal. 이 게시물vardecimal약간 더 많은 내용을 다루고 있습니다. 실제로 길이와 비슷한 길이를 저장하기 위해 열 당 2 바이트의 오버 헤드가 추가 varchar됩니다.

행 압축은 593 개마다 추가로 2 바이트 필요 numeric열을 플러스 bigintint헤드 각각 1 바이트를 필요로 할 것이다.

행 압축 스토리지 요구 사항은 다음과 같습니다

  • bigintMyTableID의 8 바이트 + 1 바이트 오버 헤드
  • intLastColumn의 경우 4 바이트 + 1 바이트 오버 헤드
  • 593 개 numeric(19,4)열 각각에 대해 9 바이트 + 2 바이트 오버 헤드
  • 1188 바이트의 ROW 압축 오버 헤드

8 + 4 + (593 * 9) = 5349 바이트 데이터

1 + 1 + (593 * 2) = 1188 바이트 행 압축 오버 헤드

행 압축 스키마의 경우 총 6537 바이트


이제 행 압축 스키마의 행 크기가 확보되었으므로 수학을 다시 방문 할 수 있습니다. 페이지 압축 행 크기는 데이터 크기 + 행 압축 오버 헤드 + 페이지 압축 오버 헤드입니다.

  • bigintMyTableID의 경우 8 바이트
  • intLastColumn의 경우 4 바이트
  • 593 개 numeric(19,4)열 각각에 대해 9 바이트
  • 1188 바이트의 ROW 압축 오버 헤드
  • 1530 바이트의 PAGE 압축 오버 헤드
  5349 바이트 데이터 
+ 1188 바이트 행 압축 오버 헤드 
+ 1530 바이트 페이지 압축 오버 헤드 

총 8067 바이트


1
"대부분의 경우 행 압축으로 공간을 절약 할 수 있지만 항상 그런 것은 아니라는 것을 알게 될 것입니다." 2718 바이트의 오버 헤드가 예상보다 훨씬 많습니다. 시간을내어 자세한 답변을 작성해 주셔서 감사합니다.
Henrik Staun Poulsen

1
@HenrikStaunPoulsen 기억해야 할 또 다른 중요한 사항은 SQL Server가 데이터를 압축 할 수 없다고 가정해야한다는 것입니다. 따라서 데이터 가 8060 바이트 미만으로 압축 되더라도 SQL Server는 압축 할 수없는 데이터 에 대한 이론적 인 최대 행 크기를 기반으로 행 크기를 계산해야합니다.
AMtwo

3 일 후에도 여전히 행 압축에 필요한 바이트 수에 놀랐습니다. 열당 2 바이트 페이지 압축은 그 위에 거의 3 바이트를 추가합니다. 그러나; 도와 주셔서 감사합니다. 가장 유용했습니다.
Henrik Staun Poulsen
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.