귀하의 질문에, 추가 옵션이 이산 열을 비교하는 것보다 빠르다는 것을 "증명"할 수 있도록 준비한 일부 테스트에 대해 자세히 설명합니다. @gbn과 @srutzky가 암시 한 것처럼 테스트 방법이 여러 가지 방식으로 결함이 있다고 생각합니다.
먼저 SQL Server Management Studio (또는 사용중인 클라이언트)를 테스트하지 않아야합니다. 예를 들어 SELECT *
3 백만 개의 행이있는 테이블에서 실행하는 경우 주로 SQL Server에서 행을 가져 와서 화면에 렌더링하는 SSMS 기능을 테스트하는 것입니다. SELECT COUNT(1)
네트워크를 통해 수백만 행을 가져 와서 화면에 렌더링해야 할 필요성을 없애는 것과 같은 것을 사용하는 것이 훨씬 좋습니다 .
둘째, SQL Server의 데이터 캐시를 알고 있어야합니다. 일반적으로 스토리지에서 데이터를 읽고 콜드 캐시에서 데이터를 처리하는 속도를 테스트합니다 (예 : SQL Server의 버퍼가 비어 있음). 간혹 웜 캐시를 사용하여 모든 테스트를 수행하는 것이 합리적이지만이를 염두에두고 명시 적으로 테스트에 접근해야합니다.
감기 캐시 테스트를 위해, 당신은 실행해야 CHECKPOINT
하고 DBCC DROPCLEANBUFFERS
시험의 각 실행하기 전에.
귀하의 질문에 대해 귀하가 요청한 테스트를 위해 다음 테스트 베드를 만들었습니다.
IF COALESCE(OBJECT_ID('tempdb..#SomeTest'), 0) <> 0
BEGIN
DROP TABLE #SomeTest;
END
CREATE TABLE #SomeTest
(
TestID INT NOT NULL
PRIMARY KEY
IDENTITY(1,1)
, A INT NOT NULL
, B FLOAT NOT NULL
, C MONEY NOT NULL
, D BIGINT NOT NULL
);
INSERT INTO #SomeTest (A, B, C, D)
SELECT o1.object_id, o2.object_id, o3.object_id, o4.object_id
FROM sys.objects o1
, sys.objects o2
, sys.objects o3
, sys.objects o4;
SELECT COUNT(1)
FROM #SomeTest;
내 컴퓨터에서 260,144,641의 수를 반환합니다.
"추가"방법을 테스트하기 위해 다음을 실행합니다.
CHECKPOINT 5;
DBCC FREEPROCCACHE;
DBCC DROPCLEANBUFFERS;
SET STATISTICS IO, TIME ON;
GO
SELECT COUNT(1)
FROM #SomeTest st
WHERE (st.A + st.B + st.C + st.D) = 0;
GO
SET STATISTICS IO, TIME OFF;
메시지 탭에 다음이 표시됩니다.
테이블 '#SomeTest'. 스캔 카운트 3, 논리적 읽기 1322661, 물리적 읽기 0, 미리 읽은 읽기 1313877, lob 논리적 읽기 0, lob 물리적 읽기 0, lob read-ahead read 0
SQL Server 실행 시간 : CPU 시간 = 49047ms, 경과 시간 = 173451ms
"이산 형 열"테스트의 경우 :
CHECKPOINT 5;
DBCC FREEPROCCACHE;
DBCC DROPCLEANBUFFERS;
SET STATISTICS IO, TIME ON;
GO
SELECT COUNT(1)
FROM #SomeTest st
WHERE st.A = 0
AND st.B = 0
AND st.C = 0
AND st.D = 0;
GO
SET STATISTICS IO, TIME OFF;
메시지 탭에서 다시 :
테이블 '#SomeTest'. 스캔 횟수 3, 논리적 읽기 1322661, 물리적 읽기 0, 미리 읽기 읽기 1322661, lob 논리적 읽기 0, lob 물리적 읽기 0, lob read-ahead 읽기 0
SQL Server 실행 시간 : CPU 시간 = 8938ms, 경과 시간 = 162581ms
위의 통계에서 두 번째 변형을 볼 수 있습니다. 이산 열은 0과 비교되고 경과 시간은 약 10 초 짧으며 CPU 시간은 약 6 배 짧습니다. 위의 테스트에서 긴 시간은 대부분 디스크에서 많은 행을 읽은 결과입니다. 행 수를 3 백만으로 줄이면 디스크 I / O의 영향이 훨씬 적기 때문에 비율은 거의 동일하지만 경과 시간이 눈에 띄게 줄어드는 것을 볼 수 있습니다.
"추가"방법으로 :
테이블 '#SomeTest'. 스캔 횟수 3, 논리적 읽기 15255, 물리적 읽기 0, 미리 읽기 0, lob 논리적 읽기 0, lob 물리적 읽기 0, lob 미리 읽기 0
SQL Server 실행 시간 : CPU 시간 = 499ms, 경과 시간 = 256ms
"이산 열"방법으로 :
테이블 '#SomeTest'. 스캔 횟수 3, 논리적 읽기 15255, 물리적 읽기 0, 미리 읽기 0, lob 논리적 읽기 0, lob 물리적 읽기 0, lob 미리 읽기 0
SQL Server 실행 시간 : CPU 시간 = 94ms, 경과 시간 = 53ms
이 테스트에서 실제로 큰 차이를 만드는 것은 무엇입니까? 다음과 같은 적절한 색인 :
CREATE INDEX IX_SomeTest ON #SomeTest(A, B, C, D);
"추가"방법 :
테이블 '#SomeTest'. 스캔 카운트 3, 논리적 읽기 14235, 물리적 읽기 0, 미리 읽기 0, lob 논리적 읽기 0, lob 물리적 읽기 0, lob 미리 읽기 0.
SQL Server 실행 시간 : CPU 시간 = 546ms, 경과 시간 = 314ms
"이산 열"방법 :
테이블 '#SomeTest'. 스캔 횟수 1, 논리적 읽기 3, 물리적 읽기 0, 미리 읽기 0, lob 논리적 읽기 0, lob 물리적 읽기 0, lob 미리 읽기 0
SQL Server 실행 시간 : CPU 시간 = 0ms, 경과 시간 = 0ms
위의 인덱스를 사용하여 각 쿼리의 실행 계획이 상당히 좋습니다.
"추가"방법은 전체 색인의 스캔을 수행해야합니다.
선행 인덱스 열 A
이 0 인 인덱스의 첫 번째 행을 검색 할 수있는 "이산 열"방법 :