1. 사전 구성
SELECT
ROW_NUMBER () OVER (ORDER BY a.number) seq
, CONVERT(INT, RIGHT(a.number*b.number*a.high, 2)) AS value
, NEWID() txt
, DATEADD(dd, b.number, '2020-01-01') date
INTO TB_Sum
FROM master..spt_values a, master..spt_values b
WHERE a.type = 'P'
AND b.type = 'P'
AND a.number BETWEEN 1 AND 1000
AND b.number BETWEEN 1 AND 1000
;
CREATE CLUSTERED INDEX CIDX_CNT ON TB_Sum(date)
;
2. AS-IS
SELECT sum_total, sum_1, sum_2, sum_3, sum_4
FROM
(SELECT SUM(value) sum_total
FROM TB_Sum
WHERE date BETWEEN '2020-01-01' AND '2020-12-31') a
CROSS JOIN
(SELECT SUM(value) sum_1
FROM TB_Sum
WHERE date BETWEEN '2020-01-01' AND '2020-03-31') b
CROSS JOIN
(SELECT SUM(value) sum_2
FROM TB_Sum
WHERE date BETWEEN '2020-04-01' AND '2020-06-30') c
CROSS JOIN
(SELECT SUM(value) sum_3
FROM TB_Sum
WHERE date BETWEEN '2020-07-01' AND '2020-09-30') d
CROSS JOIN
(SELECT SUM(value) sum_4
FROM TB_Sum
WHERE date BETWEEN '2020-10-01' AND '2020-12-31') e
;
- 각 구문에서 각 기간의 합을 구하기 위해 테이블을 총 5회 읽어내고 있음.
- 각 분기 데이터는 2020년 전체 데이터에 일부로 포함되는 데이터임에도 중복된 데이터를 읽어내어 I/O가 추라로 발생됨.
- 각 분기별 데이터를 모두 합치면 1년간의 데이터가 되기 때문에, 2020년 전체 데이터를 출력하기 위해 테이블을 읽는 것은 불필요한 I/O를 사용하는 것 이다.
- 2020년 전체 데이터를 읽어내는 인라인뷰를 제거하고 각 분기별 데이터를 합산하여 연간 데이터를 출력하면 I/O를 개선시킬 수 있다.
3. TO-BE
SELECT sum_1+sum_2+sum_3+sum_4 as sum_total
, sum_1, sum_2, sum_3, sum_4
FROM
(SELECT SUM(value) sum_1
FROM TB_Sum
WHERE date BETWEEN '2020-01-01' AND '2020-03-31') b
CROSS JOIN
(SELECT SUM(value) sum_2
FROM TB_Sum
WHERE date BETWEEN '2020-04-01' AND '2020-06-30') c
CROSS JOIN
(SELECT SUM(value) sum_3
FROM TB_Sum
WHERE date BETWEEN '2020-07-01' AND '2020-09-30') d
CROSS JOIN
(SELECT SUM(value) sum_4
FROM TB_Sum
WHERE date BETWEEN '2020-10-01' AND '2020-12-31') e
;
댓글