*MSSQL 기준
공부배경
새로 유지보수를 맡게 된 메뉴의 프로시저를 분석하는데 프로시저가 너무 길고 읽기 복잡했다.
일단 처음부터 끝까지 분석해 프로시저의 전반적인 내용은 다 파악했다.
그 다음으로 사수에게 반영을 제안할만한 리팩토링 방법을 찾아보기로 했다.
프로시저에 INNER JOIN 조건만 다른 쿼리 두 개가 UNION ALL 되어 있는 부분이 있었다.
쿼리 한 개에 조인 조건을 몰아넣어 주고 UNION ALL을 없애 코드 길이를 줄여봤다.
1. UNION ALL을 쓴 쿼리
- 쿼리 길이 51줄 / 실행속도 평균 약 0.58초
SELECT
CASE
WHEN B.AA IS NULL
OR B.AA = 'aa'
THEN '1'
ELSE '2'
END AS TYPE ,
A.BB ,
A.CC ,
A.DD ,
(
CASE
WHEN A.TIME <= '0800'
THEN CONVERT(INT,A.TIME) + '2400'
ELSE A.TIME
END
) AS TIME_FOR_CAL
FROM TABLE_1 A
INNER JOIN VIEW_1 V
ON (V.SEQ = '123' AND V.NUM = '123'+'_'+ A.ID) -- SEQ가 123
AND V.STATUS = '9'
LEFT OUTER JOIN TABLE_2 B
ON B.DATE = A.DATE
WHERE DATE BETWEEN @FROMDATE AND @TODATE
UNION ALL
SELECT
CASE
WHEN B.AA IS NULL
OR B.AA = 'aa'
THEN '1'
ELSE '2'
END AS TYPE ,
A.BB ,
A.CC ,
A.DD ,
(
CASE
WHEN A.TIME <= '0800'
THEN CONVERT(INT,A.TIME) + '2400'
ELSE A.TIME
END
) AS TIME_FOR_CAL
FROM TABLE_1 A
INNER JOIN VIEW_1 V
ON (V.SEQ = '456' AND V.NUM = '456'+'_'+ A.ID) -- SEQ가 456
AND V.STATUS = '9'
LEFT OUTER JOIN TABLE_2 B
ON B.DATE = A.DATE
WHERE DATE BETWEEN @FROMDATE AND @TODATE
2. UNION ALL 대신 INNER JOIN 조건을 추가한 쿼리
- 쿼리 길이 26줄 / 실행속도 평균 약 0.75초
SELECT
CASE
WHEN B.AA IS NULL
OR B.AA = 'aa'
THEN '1'
ELSE '2'
END AS TYPE ,
A.BB ,
A.CC ,
A.DD ,
(
CASE
WHEN A.TIME <= '0800'
THEN CONVERT(INT,A.TIME) + '2400'
ELSE A.TIME
END
) AS TIME_FOR_CAL
FROM TABLE_1 A
INNER JOIN VIEW_1 V
ON ((V.SEQ = '123' AND V.NUM = '123'+'_'+ A.ID) -- SEQ가 123
OR
(V.SEQ = '456' AND V.NUM = '456'+'_'+ A.ID)) -- SEQ가 456
AND V.STATUS = '9'
LEFT OUTER JOIN TABLE_2 B
ON B.DATE = A.DATE
WHERE DATE BETWEEN @FROMDATE AND @TODATE
결론
조인 조건이 많은 쿼리 하나를 돌리는 것보다
조인 조건이 적은 쿼리 두 개를 UNION ALL하여 돌리는 것이 더 빠를 수 있다.
테스트에서 조회된 레코드는 44줄이었는데,
실제 사용 시에는 더 많은 데이터를 불러오는 경우가 대부분이라 속도 차가 더 클 것이다.
읽기 쉬운 코드가 항상 효율적인 코드는 아니라는 건 알고 있었는데,
테스트 해보며 직접 눈으로 확인하니 공부가 됐다.
추가내용 / 2021.7.20
조인에 OR 조건이 추가되더라도
UNION ALL 대신 적절한 인덱스를 사용하는 것이 더 빠를 수 있다고 한다.
'SQL' 카테고리의 다른 글
[분석해 보세요] 결과값이 뭘까? (0) | 2021.05.18 |
---|---|
[Oracle/Tibero] 특정연도부터 올해까지의 목록 출력 (0) | 2020.07.23 |
[Oracle/Tibero] 콤보에 '전체' 추가해서 기본값으로 세팅하기 (0) | 2020.07.23 |
[MSSQL] ISNULL의 기초 이해 (0) | 2020.06.26 |
[MSSQL] 검색 조건에 LIKE와 컬럼명을 이용하는 쿼리문 (0) | 2020.04.17 |
댓글