본문 바로가기
Develop/MSSQL

MAX() 함수의 성능 개선 -2

by 3-stack 2022. 12. 19.

1. 사전구성

SELECT
  CASE WHEN a.number < 10 THEN '가'
  ELSE '나' END AS A
  , ROW_NUMBER() OVER(ORDER BY a.number) AS B
INTO TB_TOP
FROM master..spt_values a
JOIN master..spt_values b 
  ON a.type = 'P' AND a.number <= 100
  AND b.type = 'P' AND b.number <= 1000;

CREATE INDEX NIDX01_TOP ON TB_TOP (A, B);

 

table_name index_name index_description Is_Unique indexed_columns included_columns
TB_TOP NIDX01_TOP nonclustered 0 A, B [NULL]

 

2. AS-IS

SELECT A, MAX(B) AS 'MAX(B)'
FROM TB_TOP 
WHERE A = '나'
GROUP BY A;

  • 테이블의 [B] 컬럼은 NULL 값이 허용되어 있기 때문에 IS NULL과 IS NOT NULL 두 경우를 각각 실행하여 병합한다.
  • 각각 가장 큰 데이터 1건을 찾기 위해 인덱스 Backward 방향으로 스캔한다.
  • NULL 값은 인덱스 내에서 가장 선두에 존재한다.
  • 따라서 IS NULL 조건에 해당하는 데이터를 찾는 과정에서 [A] = '나'로 탐색된 데이터를 모두 읽게 된다.
  • 실제 NULL 값이 존재 하지는 않지만 IS NULL 조건인 경우에 대한 처리로 인해 불필요한 I/O가 생기게 된다.

 

3. TO_BE

SELECT A, MAX(B) AS 'MAX(B)'
FROM TB_TOP 
WHERE A = '나'
  AND B IS NOT NULL
GROUP BY A;

  1. [B] 컬럼에 대한 IS NOT NULL 조건을 명시한다.
  2. [B] 컬럼에 NOT NULL 제약조건을 적용한다.

댓글