IT 서적/친절한 SQL 튜닝
12. 친절한 SQL 튜닝
SH.DevBlog
2023. 10. 21. 20:52
728x90
소트가 발생하지 않도록 SQL 작성
UNION VS UNION ALL
- UNION을 사용하면 옵티마이저는 상단과 하단 두 집합 간 중복을 제거하려고 소트 작업을 수행
- UNION ALL은 중복을 확인하지 않고 두 집합을 단순히 결합
- 따라서, 특이한 케이스를 제외하고는 UNION ALL을 사용하는 것이 효율적이다.
UNION ALL을 사용하려면 아래와 같이 쿼리를 작성해야 한다.
SELECT 결제번호 ,결제수단코드 ,주문번호 ,결제금액 FROM 결제 WHERE 결제일자 = '20180316' UNION ALL SELECT 결제번호 ,결제수단코드 ,주문번호 ,결제금액 FROM 결제 WHERE 주문일자 = '20180316' AND 결제일자 <> '20180316'
만약에 결제일자가 'NULLABLE'로 설계돼 있다면 아래 조건을 추가해야 한다.
AND (결제일자 <> '20180316' OR 결제일자 IS NULL)' LNNVL(결제일자 = '20180316')
- LNNVL 함수는 아래의 상황일 때 조건이 TRUE이다.
컬럼이 NULL인 경우 = TRUE
함수 내부 조건이 FALSE인 경우 = TRUE
EXIST 활용
- 중복 데이터를 제거할 목적으로 DISTINCT 연산자를 종종 사용하는데, 이 연산자를 사용할 경우 모든 데이터를 읽어서 중복을 제거해야 한다.
- 모든 데이터를 읽는 과정에서는 무분별한 I/O가 발생하게 된다.
SELECT DISTINCT
P.상품번호
,P.상품명
,P.상품가격
FROM 상품 P
,계약 C
WHERE P.상품유형코드 = :pclscd
AND C.상품번호 = P.상품번호
AND C.계약일자 BETWEEN :dt1 AND :dt2
AND C.계약구분코드 = :ctpcd
- 위 쿼리를 아래와 같이 바꿔보자.
SELECT P.상품번호
,P.상품명
,P.상품가격
FROM 상품 P
WHERE P.상품유형코드 = :pclscd
AND EXIST (
SELECT 'X'
FROM 계약 C
WHERE C.상품번호 = P.상품번호
AND C.계약일자 BETWEEN :dt1 AND :dt2
AND C.계약구분코드 = :ctpcd
)
- EXIST 서브쿼리는 데이터 존재 여부만 확인하기 때문에 조건절을 만족하는 데이터를 모두 읽지 않는다.
728x90