스파링
스파 스 열에 대해 몇 가지 테스트를 수행 할 때 직접적인 원인을 알고 싶은 성능 저하가있었습니다.
DDL
하나는 4 개의 희소 열이 있고 다른 하나는 희소 열이없는 두 개의 동일한 테이블을 만들었습니다.
--Non Sparse columns table & NC index
CREATE TABLE dbo.nonsparse( ID INT IDENTITY(1,1) PRIMARY KEY NOT NULL,
charval char(20) NULL,
varcharval varchar(20) NULL,
intval int NULL,
bigintval bigint NULL
);
CREATE INDEX IX_Nonsparse_intval_varcharval
ON dbo.nonsparse(intval,varcharval)
INCLUDE(bigintval,charval);
-- sparse columns table & NC index
CREATE TABLE dbo.sparse( ID INT IDENTITY(1,1) PRIMARY KEY NOT NULL,
charval char(20) SPARSE NULL ,
varcharval varchar(20) SPARSE NULL,
intval int SPARSE NULL,
bigintval bigint SPARSE NULL
);
CREATE INDEX IX_sparse_intval_varcharval
ON dbo.sparse(intval,varcharval)
INCLUDE(bigintval,charval);
DML
그런 다음 약 2540 NON-NULL 값을 둘 다에 삽입했습니다.
INSERT INTO dbo.nonsparse WITH(TABLOCK) (charval, varcharval,intval,bigintval)
SELECT 'Val1','Val2',20,19
FROM MASTER..spt_values;
INSERT INTO dbo.sparse WITH(TABLOCK) (charval, varcharval,intval,bigintval)
SELECT 'Val1','Val2',20,19
FROM MASTER..spt_values;
그런 다음 두 테이블에 1M NULL 값을 삽입했습니다.
INSERT INTO dbo.nonsparse WITH(TABLOCK) (charval, varcharval,intval,bigintval)
SELECT TOP(1000000) NULL,NULL,NULL,NULL
FROM MASTER..spt_values spt1
CROSS APPLY MASTER..spt_values spt2;
INSERT INTO dbo.sparse WITH(TABLOCK) (charval, varcharval,intval,bigintval)
SELECT TOP(1000000) NULL,NULL,NULL,NULL
FROM MASTER..spt_values spt1
CROSS APPLY MASTER..spt_values spt2;
쿼리
스파 스가 아닌 테이블 실행
새로 작성된 비 분산 테이블에서이 조회를 두 번 실행할 때 다음을 수행하십시오.
SET STATISTICS IO, TIME ON;
SELECT * FROM dbo.nonsparse
WHERE 1= (SELECT 1) -- force non trivial plan
OPTION(RECOMPILE,MAXDOP 1);
논리적 읽기는 5257 페이지를 보여줍니다.
(1002540 rows affected)
Table 'nonsparse'. Scan count 1, logical reads 5257, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
그리고 CPU 시간은 343ms입니다
SQL Server Execution Times:
CPU time = 343 ms, elapsed time = 3850 ms.
스파 스 테이블 실행
스파 스 테이블에서 동일한 쿼리를 두 번 실행합니다.
SELECT * FROM dbo.sparse
WHERE 1= (SELECT 1) -- force non trivial plan
OPTION(RECOMPILE,MAXDOP 1);
더 낮은 1763
(1002540 rows affected)
Table 'sparse'. Scan count 1, logical reads 1763, physical reads 3, read-ahead reads 1759, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
그러나 CPU 시간은 547ms 입니다.
SQL Server Execution Times:
CPU time = 547 ms, elapsed time = 2406 ms.
질문
원래 질문
때문에 NULL의 값이 스파 스 열에 직접 저장되지 않으며, CPU 시간의 증가는 복귀로 인해 수 NULL의 결과 집합으로 값을? 아니면 설명서에 명시된대로 동작 입니까?
스파 스 열은 널이 아닌 값을 검색하기 위해 더 많은 오버 헤드 비용으로 널값에 필요한 공간을 줄입니다.
아니면 오버 헤드가 사용 된 읽기 및 스토리지에만 관련되어 있습니까?
실행 후 폐기 결과로 ssms를 실행하는 경우에도 스파 스 선택의 CPU 시간은 스파 스가 아닌 (219ms)에 비해 더 높습니다 (407ms).
편집하다
2540 만 존재하더라도 null이 아닌 값의 오버 헤드 일 수 있지만 여전히 확신하지 못합니다.
이것은 거의 같은 성능으로 보이지만 드문 요소는 손실되었습니다.
CREATE INDEX IX_Filtered
ON dbo.sparse(charval,varcharval,intval,bigintval)
WHERE charval IS NULL
AND varcharval IS NULL
AND intval IS NULL
AND bigintval IS NULL;
CREATE INDEX IX_Filtered
ON dbo.nonsparse(charval,varcharval,intval,bigintval)
WHERE charval IS NULL
AND varcharval IS NULL
AND intval IS NULL
AND bigintval IS NULL;
SET STATISTICS IO, TIME ON;
SELECT charval,varcharval,intval,bigintval FROM dbo.sparse WITH(INDEX(IX_Filtered))
WHERE charval IS NULL AND varcharval IS NULL
AND intval IS NULL
AND bigintval IS NULL
OPTION(RECOMPILE,MAXDOP 1);
SELECT charval,varcharval,intval,bigintval
FROM dbo.nonsparse WITH(INDEX(IX_Filtered))
WHERE charval IS NULL AND
varcharval IS NULL
AND intval IS NULL
AND bigintval IS NULL
OPTION(RECOMPILE,MAXDOP 1);
대략 같은 실행 시간이있는 것 같습니다 :
SQL Server Execution Times:
CPU time = 297 ms, elapsed time = 292 ms.
SQL Server Execution Times:
CPU time = 281 ms, elapsed time = 319 ms.
그런데 왜 논리 읽기가 같은 양입니까? 스파 스 열에 대해 필터링 된 인덱스가 포함 된 ID 필드와 다른 비 데이터 페이지를 제외하고 아무것도 저장하지 않아야합니까?
Table 'sparse'. Scan count 1, logical reads 5785,
Table 'nonsparse'. Scan count 1, logical reads 5785
그리고 두 지수의 크기 :
RowCounts Used_MB Unused_MB Total_MB
1000000 45.20 0.06 45.26
왜 같은 크기입니까? 희소성이 손실 되었습니까?
추가 정보
select @@version
Windows Server 2012 R2 Datacenter 6.3의 Microsoft SQL Server 2017 (RTM-CU16) (KB4508218)-14.0.3223.3 (X64) Jul 12 2019 17:43:08 Copyright (C) 2017 Microsoft Corporation Developer Edition (64 비트) 9600 :) (하이퍼 바이저)
쿼리를 실행하고 ID 필드 만 선택하는 동안 희소 테이블에 대한 논리적 읽기가 낮아 CPU 시간이 비슷합니다.
테이블 크기
SchemaName TableName RowCounts Used_MB Unused_MB Total_MB
dbo nonsparse 1002540 89.54 0.10 89.64
dbo sparse 1002540 27.95 0.20 28.14
클러스터형 또는 비 클러스터형 인덱스를 강제 실행하면 CPU 시간 차이가 유지됩니다.