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를 개선할 수 있다.
'Develop > MSSQL' 카테고리의 다른 글
스칼라 서브 쿼리 성능 이슈 (0) | 2022.12.01 |
---|---|
SPOOL 연산자 성능 개선 - 3 (0) | 2022.11.30 |
NOT IN 조건으로 사용된 서브쿼리 성능 이슈 (0) | 2022.11.22 |
SPOOL 연산자 성능 개선 - 1 (0) | 2022.11.21 |
IN 조건절 성능 이슈 (0) | 2022.11.20 |
댓글