티스토리 뷰
대량의 데이터를 처리할 경우 OR 연산이 조건에 있으면 성능 저하에 많은 영향을 줍니다. 특히 OR 조건중 어느 하나라도 인텍스가 없으면 FULL TABLE SCAN으로 풀리기
쉽죠. OR 연산을 튜닝하는 방법을 몇가지 소개해 드립니다.
예제)
매출테이블(T_TRADE)에서 상점(ID: A, B) 인 상점의 특정 거래일(TR_DT) 동안의 총 매출액(AMT)를 구하라.
1. OR 조건을 UNION ALL로 풀어냄
: 쉽게 작성할 수 있으나 SQL이 풀어낸 개수만큼 늘어나 유지보수가 어려움.
SELECT ID, SUM(AMT)
FROM
(
SELECT AMT
FROM T_TRADE
WHERE TR_DT IN (SELECT DT FROM COPY_YMD_T WHERE DT BETWEEN '시작일' AND '종료일') -- 선분조건 튜닝
AND ID = 'A'
UNION ALL
SELECT AMT
FROM T_TRADE
WHERE TR_DT IN (SELECT DT FROM COPY_YMD_T WHERE DT BETWEEN '시작일' AND '종료일')
AND ID = 'B'
)
GROUP BY ID
2. CONCATENATION 으로 푸는 방법
SELECT ID, SUM(AMT)
FROM
(
SELECT /*+ use_concat */ AMT
FROM T_TRADE
WHERE TR_DT IN (SELECT DT
FROM COPY_YMD_T
WHERE DT BETWEEN '시작일' AND '종료일'
AND ROWNUM >= '0') -- ROWNUM >= '0'은 이 쿼리가 먼저 실행 되도
록 하기 위해서임. GROUP BY DT를
사용해도 동일한 효과를 낼 수 있음.
단 DT는 INDEX가 있어야 함.
AND ID IN('A','B')
)
GROUP BY ID
3. IN의 변형
SELECT ID, SUM(AMT)
FROM
(
SELECT /*+ use_concat */ AMT
FROM T_TRADE
WHERE TR_DT IN (SELECT DT
FROM COPY_YMD_T
WHERE DT BETWEEN '시작일' AND '종료일'
AND ROWNUM >= '0') -- ROWNUM >= '0'은 이 쿼리가 먼저 실행 되도록 하기 위해서임. GROUP BY DT를
사용해도 동일한 효과를 낼 수 있음. 단 DT는 INDEX가 있어야 함.
AND ID IN (SELECT ID
FROM
( SELECT 'A' FROM DUAL
UNION ALL
SELECT 'B' FROM DUAL
) -- IN을 변형함으로써 실행계획을 바꿔 성능을 튜닝할 수 있음.
)
GROUP BY ID
4. DECODE문을 이용하는 방법
: 위 조건에서는 스위칭성 조건이 없어서 사용할 수 없으나 스위칭성 조건이 있는 OR일 경우 매우 강력한 방법임
A = DECODE(:SW, '1','A',''B') 같이 OR를 = 조건으로 바꿀 수가 있음.
PS. 방법 3은 아직 정확한 이유를 모르고 우연히 발견한 것으로 IN ('A',''B') 와 뭐가
다른지 모르겠더군요. 더 연구가 필요합니다. ㅎㅎ
혹시 이유를 아시는 분은 댓글을 달아 주세요.
- Total
- Today
- Yesterday
- 코라나 19
- 톡토기
- 오미크론
- 르세라핌
- 매직 트랙패드2
- VARIDESK
- Life Chair
- node.js
- 별잉 빛나는 밤
- 홈 오피스
- 증권정보포털
- 별이 빚나는 밤
- 고체 향수
- JMW 헤어드라이기기
- 루미큐브 종류
- 브리다 정수기
- GKRS
- 남설 팔찌
- 카카오 에드
- 빈센트 반 고흐
- weka
- Sybase IQ
- 화분벌레
- 배당급
- yugabyteDB
- 유가바이트디비
- Pixel Pals
- 파나소닉 비데 DL-EH10KWS
- 솔리드 쿨론
- 로니카 BCS
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |