1. 사전구성
SELECT a.number num
, CHAR(LEFT(b.high, 1) + 64) txt
, LEFT(a.low, 1) group_id
INTO TB_FSpool03
FROM master..spt_values a, master..spt_values b
WHERE a.type = 'P'
AND a.number BETWEEN 1 AND 100
AND b.type = 'P'
AND b.number BETWEEN 1 AND 100
;
CREATE INDEX NIDX01_FSpool03 ON TB_FSpool03 (group_id) INCLUDE (num, txt);
table_name |
index_name |
index_description |
Is_Unique |
indexed_columns |
included_columns |
TB_FSpool03 |
NIDX01_FSpool03 |
nonclustered |
0 |
group_id |
num, txt |
All density |
Average Length |
Columns |
0.1111111119 |
1 |
group_id |
RANGE_HI_KEY |
RANGE_HI_KEY |
EQ_ROWS |
DISTINCT_RANGE_ROWS |
AVG_RANGE_ROWS |
1 |
0 |
3,600 |
0 |
1 |
2 |
0 |
800 |
0 |
1 |
3 |
0 |
800 |
0 |
1 |
4 |
0 |
800 |
0 |
1 |
5 |
0 |
800 |
0 |
1 |
6 |
0 |
800 |
0 |
1 |
7 |
0 |
800 |
0 |
1 |
8 |
0 |
800 |
0 |
1 |
9 |
0 |
800 |
0 |
1 |
2. AS-IS
SELECT COUNT(DISTINCT num) num_cnt
, COUNT(DISTINCT txt) txt_cnt
FROM TB_FSpool03
WHERE group_id = '7';
- 각 컬럼 별로 중복 제거된 행을 추출하기 위해선 컬럼마다 데이터를 새로 읽어내야 한다.
이를 위해서 조건절로 탐색된 8천 건의 데이터를 임시 테이블로 저장한다.
이를 재사용하면서 결과값을 추출한다.
- 중간 결과 집합 전체를 임시 테이블로 저장하고 재사용하기 위해서 Table Spool (Eager Spool)이 사용된다.
수행하는 과정에서 임시 테이블에 대한 I/O 비용이 높게 발생한다.
3. TO_BE
SELECT num_cnt, txt_cnt
FROM
(SELECT COUNT(DISTINCT num) num_cnt
FROM TB_FSpool03
WHERE group_id = '7') a
, (SELECT COUNT(DISTINCT txt) txt_cnt
FROM TB_FSpool03
WHERE group_id = '7') b
;
- 두 컬럼에 대해 중복 값이 제거된 행을 추출하기 위해 인덱스로 탐색된 8천 건의 데이터를 임시 테이블로 저장하고,
재사용하면서 많은 I/O가 사용되었다.
- COUNT(DISTINCT num)와 COUNT(DISTINCT txt)의 값을 각각 조회하도록 구문을 분리하고,
두 결과를 조인하도록 변경하면 임시 데이터를 만들고 사용하는 비용을 제거할 수 있기 때문에 I/O를 개선할 수 있다.
댓글