Ex)
100 + NULL = NULL
- NULL값은 어떤 값과도 연산이 되지 않고 NULL값을 리턴
성능개선 전 SQL
SQL> SELECT SUM (
t1.sum_c3
- ((SELECT SUM(c3) FROM null_t2 t2 WHERE t2.c1 = t1.c1 AND t2.c2 = t1.c2)
+ (SELECT SUM(c3) FROM null_t3 t3 WHERE t3.c1 = t1.c1 AND t3.c2 = t1.c2))
) AS total_sum
FROM (SELECT c1,
c2,
SUM(c3) AS sum_c3
FROM null_t1
WHERE c2 = 'A'
GROUP BY c1, c2) t1;
TOTAL_SUM
----------
461,381,537
성능 문제점
- 인라인 뷰안에 있는 결과 집합 만큼 메인 쿼리의 SELECT-LIST절에 서브쿼리를 수행하면서 성능 저하
성능개선 후 SQL
SQL> SELECT /*+ LEADING(T1) USE HASH(T1 T2 T3) */
SUM(t1.c3_sum - (t2.c3_sum + t3.c3_sum)) AS total_sum
FROM (SELECT c1
,c2
,SUM(c3) AS c3_sum
FROM NULL_T1
WHERE c2 = 'A'
GROUP BY c1, c2 ) t1
,(SELECT c1
,c2
,SUM(c3) AS c3_sum
FROM NULL_T2
GROUP BY c1, c2 ) t2
,(SELECT c1
,c2
,SUM(c3) AS c3_sum
FROM NULL_T3
GROUP BY c1, c2 ) t3
WHERE t1.c1 = t2.c1(+)
AND t1.c2 = t2.c2(+)
AND t1.c1 = t3.c1(+)
AND t1.c2 = t3.c2(+);
TOTAL_SUM
----------
461,381,537
- 스칼라 서브쿼리를 인라인 뷰 Rows수 많큼 호출 하던 것을 HASH JOIN을 통해 성능 개선
데이터 접합성 문제점
1. 인라인 뷰 T1에서는 NULL 데이터가 추출되지 않는다.
2. T2.C3, T3.C3은 Nullable 컬럼이고, NULL이 추출된 경우에는 T1.C3_SUM값을 그대로 추출하여야 한다.
최종 개선 한 SQL
SQL> SELECT /*+ LEADING(T1) USE HASH(T1 T2 T3) */
--SUM(t1.c3_sum - (t2.c3_sum + t3.c3_sum)) AS total_sum
SUM(t1.c3_sum - (NVL(t2.c3_sum,0) + NVL(t3.c3_sum,0))) AS total_sum
FROM (SELECT c1
,c2
,SUM(c3) AS c3_sum
FROM NULL_T1
WHERE c2 = 'A'
GROUP BY c1, c2 ) t1
,(SELECT c1
,c2
,SUM(c3) AS c3_sum
FROM NULL_T2
GROUP BY c1, c2 ) t2
,(SELECT c1
,c2
,SUM(c3) AS c3_sum
FROM NULL_T3
GROUP BY c1, c2 ) t3
WHERE t1.c1 = t2.c1(+)
AND t1.c2 = t2.c2(+)
AND t1.c1 = t3.c1(+)
AND t1.c2 = t3.c2(+);
TOTAL_SUM
----------
576,734,568 <-- NULL값으로 누락 되었던 데이터 정상 추출!!
- 다른 그룹함수인 COUNT, SUM, MAX, MIN의 NULL 처리 수행 방법
SQL> SELECT 'NULL' AS NULLABLE
,COUNT(C3) AS COUNT_C3
,SUM(C3) AS SUM_C3
,MAX(C3) AS MAX_C3
,MIN(C3) AS MIN_C3
FROM NULL_T2
WHERE C3 IS NULL
AND C2 = 'A'
UNION ALL
SELECT 'NOT NULL'
,COUNT(C3)
,SUM(C3)
,MAX(C3)
,MIN(C3)
FROM NULL_T2
WHERE C3 IS NOT NULL
AND C2 = 'A'
UNION ALL
SELECT 'ALL'
,COUNT(C3)
,SUM(C3)
,MAX(C3)
,MIN(C3)
FROM NULL_T2
WHERE C2 = 'A';
NULLABLE COUNT_C3 SUM_C3 MAX_C3 MIN_C3
---------------- ---------- ---------- --------- ------
NULL 0
NOT NULL 3077 15386 8 2
ALL 3077 15386 8 2
정리
- COUNT를 제외한 SUM, MAX, MIN,은 NULL 데이터를 NULL로 리턴
- 추출된 데이터를 이용하여 또 다른 수식 연산이 별도로 진행되어야 하는 경우에는 반드시 NVL처리