다음을 통해 공유


데이터 웨어하우징의 Columnstore 인덱스

적용 대상: Microsoft Fabric의 SQL Server Azure SQL Database Azure SQL Managed Instance Analytics Platform System(PDW) SQL 데이터베이스

Columnstore 인덱스는 분할과 함께 SQL Server 데이터 웨어하우스를 빌드하는 필수 요소입니다. 이 문서에서는 SQL 데이터베이스 엔진 사용하는 데이터 웨어하우징 디자인의 주요 사용 사례 및 예제에 중점을 둡니다.

데이터 웨어하우징의 주요 기능

SQL Server 2016(13.x)에서는 columnstore 성능 향상을 위해 다음과 같은 기능을 도입했습니다.

  • Always On은 읽기 가능 복제본에 대한 columnstore 인덱스 쿼리를 지원합니다.
  • MARS(Multiple Active Result Set)는 columnstore 인덱스를 지원합니다.
  • 새로운 동적 관리 뷰 sys.dm_db_column_store_row_group_physical_stats(Transact-SQL)는 행 그룹 수준에서 성능 문제 해결 정보를 제공합니다.
  • columnstore 인덱스의 단일 스레드 쿼리는 일괄 처리 모드에서 실행할 수 있습니다. 이전에는 다중 스레드 쿼리만 일괄 처리 모드에서 실행 가능했습니다.
  • SORT 연산자는 일괄 처리 모드에서 실행됩니다.
  • 일괄 처리 모드에서 여러 DISTINCT 작업이 실행됩니다.
  • 이제 창 집계는 데이터베이스 호환성 수준 130 이상에 대한 일괄 처리 모드로 실행됩니다.
  • 집계의 효율적인 처리를 위한 집계 푸시다운입니다. 모든 데이터베이스 호환성 수준에서 지원됩니다.
  • 문자열 조건자의 효율적인 처리를 위한 문자열 조건자 푸시다운입니다. 모든 데이터베이스 호환성 수준에서 지원됩니다.
  • 데이터베이스 호환성 수준 130 이상에 대한 스냅샷 격리입니다.
  • 정렬된 클러스터 columnstore 인덱스는 SQL Server 2022(16.x)에서 도입되었습니다. 자세한 내용은 정렬된 클러스터형 columnstore 인덱스를 사용하여 CREATE COLUMNSTORE INDEX성능 튜닝을 참조하세요. 순서가 지정된 columnstore 인덱스 가용성은 Ordered 열 인덱스 가용성을 참조 하세요.

SQL Server 및 Azure SQL 버전 및 플랫폼의 새로운 기능에 대한 자세한 내용은 columnstore 인덱스의 새로운 기능을 참조하세요.

비클러스터형 인덱스와 columnstore 인덱스를 결합하여 성능 향상

SQL Server 2016(13.x)부터 클러스터형 columnstore 인덱스에 rowstore 비클러스터형 인덱스를 정의할 수 있습니다.

예: 비클러스터형 인덱스를 사용하여 테이블 검색의 효율성 향상

Data Warehouse에서 테이블 검색의 효율성을 개선하기 위해 테이블 검색에 가장 적합한 쿼리를 실행하도록 설계된 비클러스터형 인덱스를 만들 수 있습니다. 예를 들어 일치하는 값을 찾고 작은 범위의 값을 반환하는 쿼리는 columnstore 인덱스보다 B-트리 인덱스에 대해 성능이 더 좋습니다. 왜냐하면 columnstore 인덱스를 통한 전체 테이블 검색이 필요하지 않으며 B-트리 인덱스를 통해 이진 검색을 수행하여 정확한 결과를 더 빠르게 반환하기 때문입니다.

--BASIC EXAMPLE: Create a nonclustered index on a columnstore table.  
  
--Create the table  
CREATE TABLE t_account (  
    AccountKey int NOT NULL,  
    AccountDescription nvarchar (50),  
    AccountType nvarchar(50),  
    UnitSold int  
);  
GO  
  
--Store the table as a columnstore.  
CREATE CLUSTERED COLUMNSTORE INDEX taccount_cci ON t_account;  
GO  
  
--Add a nonclustered index.  
CREATE UNIQUE INDEX taccount_nc1 ON t_account (AccountKey);  

예: 비클러스터형 인덱스를 사용하여 columnstore 테이블에 기본 키 제약 조건을 적용합니다.

기본적으로 columnstore 테이블은 클러스터형 기본 키 제약 조건을 허용하지 않습니다. 이제 비클러스터형 인덱스를 사용하여 columnstore 테이블에 기본 키 제약 조건을 적용할 수 있습니다. 기본 키는 NULL이 아닌 열에 대한 UNIQUE 제약 조건에 해당하며 SQL Server는 UNIQUE 제약 조건을 비클러스터형 인덱스로 구현합니다. 이러한 사실을 결합하여 다음 예제에서는 NULL이 아닌 열 accountkey에 대해 UNIQUE 제약 조건을 정의합니다. 그 결과 기본 키 제약 조건을 NULL이 아닌 열에 UNIQUE 제약 조건으로 적용하는 비클러스터형 인덱스가 생성됩니다.

다음으로 테이블은 클러스터형 columnstore 인덱스로 변환됩니다. 변환하는 동안 비클러스터형 인덱스는 유지됩니다. 그 결과는 기본 키 제약 조건을 적용하는 비클러스터형 인덱스를 포함한 클러스터형 columnstore 인덱스입니다. columnstore 테이블에 대한 업데이트 또는 삽입은 비클러스터형 인덱스에도 영향을 주므로 고유 제약 조건을 위반하고 NULL이 아닌 모든 작업은 전체 작업이 실패합니다.

그 결과는 두 인덱스에서 기본 키 제약 조건을 적용하는 비클러스터형 인덱스를 포함한 columnstore 인덱스입니다.

--EXAMPLE: Enforce a primary key constraint on a columnstore table.   
  
--Create a rowstore table with a unique constraint.  
--The unique constraint is implemented as a nonclustered index.  
CREATE TABLE t_account (  
    AccountKey int NOT NULL,  
    AccountDescription nvarchar (50),  
    AccountType nvarchar(50),  
    UnitSold int,  
  
    CONSTRAINT uniq_account UNIQUE (AccountKey)  
);  
  
--Store the table as a columnstore.   
--The unique constraint is preserved as a nonclustered index on the columnstore table.  
CREATE CLUSTERED COLUMNSTORE INDEX t_account_cci ON t_account  
  
--By using the previous two steps, every row in the table meets the UNIQUE constraint  
--on a non-NULL column.  
--This has the same end-result as having a primary key constraint  
--All updates and inserts must meet the unique constraint on the nonclustered index or they will fail.  
  
--If desired, add a foreign key constraint on AccountKey.  
  
ALTER TABLE [dbo].[t_account]  
WITH CHECK ADD FOREIGN KEY([AccountKey]) REFERENCES my_dimension(Accountkey); 

행 수준 및 행 그룹 수준 잠금을 사용하도록 설정하여 성능 향상

columnstore 인덱스 기능의 비클러스터형 인덱스를 보완하기 위해 SQL Server 2016(13.x)은 선택, 업데이트 및 삭제 작업을 위한 세분화된 잠금 기능을 제공합니다. columnstore 인덱스에 대한 전체 테이블 검사에서 비클러스터형 인덱스 및 행 그룹 수준 잠금에 대해 인덱스 검색에 행 수준 잠금을 사용하여 쿼리를 실행할 수 있습니다. 행 수준 및 행 그룹 수준 잠금을 적절하게 사용하여 읽기/쓰기 동시성을 높이려면 이 방법을 사용합니다.

--Granular locking example  
--Store table t_account as a columnstore table.  
CREATE CLUSTERED COLUMNSTORE INDEX taccount_cci ON t_account  
GO  
  
--Add a nonclustered index for use with this example  
CREATE UNIQUE INDEX taccount_nc1 ON t_account (AccountKey);  
GO  
  
--Look at locking with access through the nonclustered index  
SET TRANSACTION ISOLATION LEVEL repeatable read;  
GO  
  
BEGIN TRAN  
    -- The query plan chooses a seek operation on the nonclustered index  
    -- and takes the row lock  
    SELECT * FROM t_account WHERE AccountKey = 100;  
COMMIT TRAN  

스냅샷 격리 및 읽기 커밋된 스냅샷 격리

SI(스냅샷 격리)를 사용하여 트랜잭션 일관성을 보장하고 RCSI(읽기 커밋된 스냅샷 격리)를 사용하여 columnstore 인덱스의 쿼리에 대한 문 수준 일관성을 보장합니다. 이렇게 하면 데이터 기록기를 차단하지 않고 쿼리를 실행할 수 있습니다. 이 비차단 동작 덕분에 복잡한 트랜잭션에 대한 교착 상태의 가능성이 크게 줄어듭니다. 자세한 내용은 SQL Server에서의 스냅샷 격리를 참조하세요.