columnstore 인덱스의 ID 열


9

반복되는 데이터가 많고 NULL열이 많은 매우 큰 테이블 IMO (~ 1 억 3 천 1 백만 행)가 있습니다.

내가있는 테이블을 사용하여이 탐험 고려하고 COLUMNSTORE INDEX그리고 나는이 IDENTITY모든 행이 고유 한 곳에 내 유일한 열입니다 원래 테이블에서 열을.

이 열을 그대로 두거나 포함시켜야합니까? 나는 당신이 테이블의 모든 행을 포함하고 싶다는 것을 읽었 COLUMNSTORE INDEX지만 가장 좋은 후보는 고유하지 않은 행이 많은 열이라는 것을 읽었습니다.

이것은 단지 나쁜 후보 COLUMNSTORE INDEX입니까?

SQL Server 2012를 사용하고 있으므로 클러스터되지 않은 열 저장소입니다. 이 데이터를 저장하는 더 좋은 방법을 모색 중입니다. 업데이트가 존재하지 않지만 ELT 프로세스를 통해 새 행이 주기적으로 추가되므로 일부 작업이 완료되었다고 가정합니다. 일부 사람들은이 데이터를 마이닝하여 대량의 보고서를 스캔하고 많은 행을 스캔하여 서버를 크롤링하여 매일 사본을 보조 서버로 오프로드하도록했습니다.


1
원래 테이블의 ID 열도 클러스터형 인덱스입니까? 그렇다면 SQL Server는 명시 적으로 요청하지 않더라도 클러스터되지 않은 columnstore 인덱스에 해당 열을 자동으로 포함합니다. 이는 클러스터형 인덱스 열이 클러스터되지 않은 b- 트리 인덱스에 포함되는 방식과 다소 유사하지만이 경우 데이터는 실제 압축 된 열 저장소 세그먼트로 저장됩니다. 자세한 정보는 dba.stackexchange.com/questions/103722/… 를 참조하십시오 .
Geoff Patterson

137 million rows크지 만 관리하기 쉽습니다. 테이블을 분할하여 다른 파일 그룹에 놓는 방법을 살펴 보셨습니까? SQL 2012의 Columnsstore 인덱스는 쓰기 가능하지 않으므로 문제가 발생할 수 있습니다.이를 삭제하고 다시 만들어야합니다. columnstore의 의사는 나쁘지 않지만 다른 옵션도 탐색하는 것이 좋습니다.
Kin Shah

답변:


11

ID 열은 SQL Server 2012 또는 SQL Server 2014의 Columnstore 인덱스에서 실제로 압축되지는 않습니다. 모두 실제로 발생하는 작업 부하에 따라 달라집니다. 워크로드에 ID 열이 포함되면 세그먼트 제거를 매우 아름답게 활용할 수 있습니다 .

압축 관점에서 볼 때-Columnstore는 일반적으로 페이지보다 더 나은 압축을 제공합니다. 일반적으로 프로덕션으로 진행하기 전에 테스트하십시오.

SQL Server 2012에서 가장 큰 문제는 배치 모드를 매우 약하게 구현하는 것이므로 수행 할 수있는 작업이 없습니다.


7
니코를 환영합니다 !!!
Aaron Bertrand

3

나는 다른 답변 (환영합니다, Niko!)으로 Niko에 가입하는 것을 거부 할 수 없었습니다. 일반적으로, 나는 SQL 2012배치 모드 제한 (Niko가 자신의 블로그에 링크하지 않는 경우 :))이 주요 관심사 일 수 있다는 Niko에 동의합니다 . 그러나 그와 함께 살 수 있고 신중하게 조사하기 위해 테이블에 대해 작성하는 모든 쿼리를 완전히 제어 할 수 있다면 columnstore는 SQL 2012에서 효과적 일 수 있습니다.

신원 열에 대한 귀하의 특정 질문에 대해서는 신원 열이 매우 잘 압축되어 초기 테스트에서 열 저장소 색인에 포함시키는 것이 좋습니다. (identity 열이 b-tree의 클러스터 된 인덱스이기도 한 경우 비 클러스터형 columnstore 인덱스에 자동으로 포함됩니다 .)

참고로, ~ 10MM 행의 식별 열 데이터에서 관찰 한 크기는 다음과 같습니다. 최적의 세그먼트 제거를 위해로드 된 열 저장소는 26MB ( PAGE행 저장소 테이블 압축의 경우 113MB) 로 압축되며 무작위로 정렬 된 b- 트리에 빌드 된 열 저장소도 40MB에 불과합니다. 따라서 이것은 최고의 b-tree 압축보다 SQL이 제공해야 할 최적의 세그먼트 제거를 위해 데이터를 정렬하지 않아도 (b-tree를 만든 다음 수행 할 때) 압축에 큰 이점을 보여줍니다. MAXDOP1)로 열 상점을 구축하십시오 .

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

다음은 내가 놀고 싶을 때 사용한 전체 스크립트입니다.

-- Confirm SQL version
SELECT @@version
--Microsoft SQL Server 2012 - 11.0.5613.0 (X64) 
--  May  4 2015 19:05:02 
--  Copyright (c) Microsoft Corporation
--  Enterprise Edition: Core-based Licensing (64-bit) on Windows NT 6.3 <X64> (Build 9600: )


-- Create a columnstore table with identity column that is the primary key
-- This will yield 10 columnstore segments @ 1048576 rows each
SELECT i = IDENTITY(int, 1, 1), ROW_NUMBER() OVER (ORDER BY randGuid) as randCol
INTO #testIdentityCompression_sortedColumnstore
FROM (
    SELECT TOP 10485760 ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS randI, NEWID() AS randGuid
    FROM master..spt_values v1
    CROSS JOIN master..spt_values v2
    CROSS JOIN master..spt_values v3
) r
ORDER BY r.randI
GO
ALTER TABLE #testIdentityCompression_sortedColumnstore
ADD PRIMARY KEY (i)
GO
-- Load using a pre-ordered b-tree and one thread for optimal segment elimination
-- See http://www.nikoport.com/2014/04/16/clustered-columnstore-indexes-part-29-data-loading-for-better-segment-elimination/
CREATE NONCLUSTERED COLUMNSTORE INDEX cs_#testIdentityCompression_sortedColumnstore ON #testIdentityCompression_sortedColumnstore (i) WITH (MAXDOP = 1)
GO

-- Create another table with the same data, but randomly ordered
SELECT *
INTO #testIdentityCompression_randomOrderColumnstore
FROM #testIdentityCompression_sortedColumnstore
GO
ALTER TABLE #testIdentityCompression_randomOrderColumnstore
ADD UNIQUE CLUSTERED (randCol)
GO
CREATE NONCLUSTERED COLUMNSTORE INDEX cs_#testIdentityCompression_randomOrderColumnstore ON #testIdentityCompression_randomOrderColumnstore (i) WITH (MAXDOP = 1)
GO

-- Create a b-tree with the identity column data and no compression
-- Note that we copy over only the identity column since we'll be looking at the total size of the b-tree index
-- If anything, this gives an unfair "advantage" to the rowstore-page-compressed version since more
-- rows fit on a page and page compression rates should be better without the "randCol" column.
SELECT i
INTO #testIdentityCompression_uncompressedRowstore
FROM #testIdentityCompression_sortedColumnstore
GO
ALTER TABLE #testIdentityCompression_uncompressedRowstore
ADD PRIMARY KEY (i)
GO

-- Create a b-tree with the identity column and page compression
SELECT i
INTO #testIdentityCompression_compressedRowstore
FROM #testIdentityCompression_sortedColumnstore
GO
ALTER TABLE #testIdentityCompression_compressedRowstore
ADD PRIMARY KEY (i)
WITH (DATA_COMPRESSION = PAGE)
GO

-- Compare all the sizes!
SELECT OBJECT_NAME(p.object_id, 2) AS tableName, COUNT(*) AS num_segments, SUM(on_disk_size / (1024.*1024.)) as size_mb
FROM tempdb.sys.partitions p
JOIN tempdb.sys.column_store_segments s
    ON s.partition_id = p.partition_id
    AND s.column_id = 1
WHERE p.object_id IN (OBJECT_ID('tempdb..#testIdentityCompression_sortedColumnstore'),OBJECT_ID('tempdb..#testIdentityCompression_randomOrderColumnstore'))
GROUP BY p.object_id
UNION ALL
SELECT OBJECT_NAME(p.object_id, 2) AS tableName
    , NULL AS num_segments
    , (a.total_pages*8.0) / (1024.0) as size_mb
FROM tempdb.sys.partitions p
JOIN tempdb.sys.allocation_units a
    ON a.container_id = p.partition_id
WHERE p.object_id IN (OBJECT_ID('tempdb..#testIdentityCompression_compressedRowstore'),OBJECT_ID('tempdb..#testIdentityCompression_uncompressedRowstore'))
ORDER BY 3 ASC
GO

모든 훌륭한 답변에 감사드립니다. 지금은 적어도 SQL Server 2014를 시작할 수있을 때까지 연기하기로 결정했습니다. 내년에 희망을 갖기 위해 업그레이드를 강화하고 있습니다.
Don
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.