[Oracle] INTERSECT, MINUS -> JOIN, NOT EXISTS
1. before SQL & plan
DELETE TIMAGECOMPLETE
WHERE (OWNERID, ORDERID) IN (
(SELECT OWNERID, ORDERID
FROM TIMAGECOMPLETE
INTERSECT
SELECT OWNERID, ORDERID
FROM TTASKTRANSHI)
MINUS
SELECT OWNERID, ORDERID
FROM TTASKTRANS)
Execution Plan
--------------------------------------------------------------------------------
0 DELETE STATEMENT Optimizer=CHOOSE (Cost=260K Card=3K Bytes=108K)
1 0 DELETE OF 'TIMAGECOMPLETE'
2 1 NESTED LOOPS (Cost=260K Card=3K Bytes=108K)
3 2 VIEW OF 'SYS.VW_NSO_1' (Cost=260K Card=3K Bytes=62K)
4 3 MINUS
5 4 INTERSECTION
6 5 SORT (UNIQUE) (Card=3K Bytes=46K)
7 6 INDEX (FAST FULL SCAN) OF 'TIMAGECOMPLETE_PK' (UNIQUE) (Cost=3 Card=3K Bytes=46K)
8 5 SORT (UNIQUE) (Card=32M Bytes=549M)
9 8 TABLE ACCESS (FULL) OF 'TTASKTRANSHI' (Cost=133K Card=32M Bytes=549M)
10 4 SORT (UNIQUE) (Card=378K Bytes=6M)
11 10 TABLE ACCESS (FULL) OF 'TTASKTRANS' (Cost=2K Card=378K Bytes=6M)
12 2 INDEX (UNIQUE SCAN) OF 'TIMAGECOMPLETE_PK' (UNIQUE) (Card=1 Bytes=18)
1.1 문제점 및 해결책
- INTERSECT 와 MINUS 인해 TTASKTRANSHI, TTASKTRANS 테이블에 대해 full table scan이 발생하여 성능저하 현상이 발생과 동시에 Lock holding이 발생함.
- INTERSECT와 MINUS를 join 및 not exists로 변경하여 성능개선 가능.
- 업무담당자와 협의 및 데이터 검증 필요.
2. After SQL & plan
DELETE TIMAGECOMPLETE
WHERE (OWNERID, ORDERID) IN (
SELECT A.OWNERID, A.ORDERID
FROM TIMAGECOMPLETE A, TTASKTRANSHI B
WHERE 1 = 1
AND A.OWNERID = B.OWNERID
AND A.ORDERID = B.ORDERID
AND NOT EXISTS (
SELECT 1
FROM TTASKTRANS C
WHERE 1 = 1
AND A.OWNERID = C.OWNERID
AND A.ORDERID = C.ORDERID))
Execution Plan
--------------------------------------------------------------------------------
0 DELETE STATEMENT Optimizer=CHOOSE (Cost=8K Card=1 Bytes=42)
1 0 DELETE OF 'TIMAGECOMPLETE'
2 1 MERGE JOIN (SEMI) (Cost=8K Card=1 Bytes=42)
3 2 INDEX (FULL SCAN) OF 'TIMAGECOMPLETE_PK' (UNIQUE) (Cost=12 Card=3K Bytes=46K)
4 2 SORT (UNIQUE) (Cost=8K Card=2M Bytes=37M)
5 4 VIEW OF 'SYS.VW_NSO_1' (Cost=5M Card=2M Bytes=37M)
6 5 FILTER
7 6 NESTED LOOPS (Cost=136 Card=2M Bytes=55M)
8 7 INDEX (FAST FULL SCAN) OF 'TIMAGECOMPLETE_PK' (UNIQUE) (Cost=3 Card=132 Bytes=2K)
9 7 INDEX (RANGE SCAN) OF 'TTASKTRANSHI_IDX02' (NON-UNIQUE) (Cost=3 Card=12K Bytes=214K)
10 6 INDEX (RANGE SCAN) OF 'TTASKTRANS_IDX02' (NON-UNIQUE) (Cost=3 Card=1 Bytes=18)
'DB Tuning' 카테고리의 다른 글
[Oracle] LEADING HINT (0) | 2014.04.28 |
---|---|
[Oracle] HINT 정리 (0) | 2014.04.28 |
[Oracle] SUBQUERY -> INLINE VIEW (0) | 2014.04.28 |
[Oracle] 각 테이블/인덱스 사이즈 조회 쿼리
## 테이블 사이즈 조회 쿼리
SELECT A.SEGMENT_NAME,
ROUND(SUM(A.BYTES)/1024/1024) "SIZE_MB",
ROUND(SUM(A.BYTES)/1024/1024/1024) "SIZE_GB",
A.SEGMENT_TYPE
FROM DBA_SEGMENTS A,
DBA_TABLES B
WHERE A.SEGMENT_NAME = B.TABLE_NAME
AND A.SEGMENT_TYPE IN ('TABLE','TABLE PARTITION')
AND A.OWNER = '유저아이디'
GROUP BY A.SEGMENT_NAME, A.SEGMENT_TYPE
ORDER BY 2 DESC;
## 인덱스 사이즈 조회 쿼리
SELECT A.SEGMENT_NAME,
ROUND(SUM(A.BYTES)/1024/1024) "SIZE_MB",
ROUND(SUM(A.BYTES)/1024/1024/1024) "SIZE_GB",
A.SEGMENT_TYPE
FROM DBA_SEGMENTS A,
DBA_INDEXES B
WHERE A.SEGMENT_NAME = B.INDEX_NAME
AND A.SEGMENT_TYPE IN ('INDEX','INDEX PARTITION')
AND A.OWNER = '유저아이디'
GROUP BY A.SEGMENT_NAME, A.SEGMENT_TYPE
ORDER BY 2 DESC;
*** TABLE PARTITION
세그먼트가 분할된 테이블을 말한다.
분할에 사용되는 정보입력은 Value 이며 이는 Hash / Range / List 등으로 나뉘어진다.
'Database / Sql' 카테고리의 다른 글
[Oracle] 16진수 <-> 10진수 변환 (0) | 2014.09.18 |
---|---|
[Oracle] IO를 많이 발생시키는 쿼리 찾기 (0) | 2014.09.02 |
[Oracle] 테이블 스페이스 용량/사용량 산출 (0) | 2014.03.04 |
[Oracle] SID, SPID 를 통해 수행하고 있는 쿼리 찾기 (0) | 2013.11.27 |
[Oracle] SYS_CONNECT_BY_PATH 문자열 합치기?? (0) | 2013.10.18 |
[Oracle] 테이블 스페이스 용량/사용량 산출
// TABLESPACE_NAME 별로 합처리
SELECT SUBSTR(A.TABLESPACE_NAME,1,30) TABLESPACE,
ROUND(SUM(A.TOTAL1)/1024/1024,1) "TOTALMB",
ROUND(SUM(A.TOTAL1)/1024/1024,1)-ROUND(SUM(A.SUM1)/1024/1024,1) "USEDMB",
ROUND(SUM(A.SUM1)/1024/1024,1) "FREEMB",
ROUND((ROUND(SUM(A.TOTAL1)/1024/1024,1)-ROUND(SUM(A.SUM1)/1024/1024,1))
/ROUND(SUM(A.TOTAL1)/1024/1024,1)*100,2) "USED%"
FROM
(SELECT TABLESPACE_NAME,0 TOTAL1,SUM(BYTES) SUM1,MAX(BYTES) MAXB,
COUNT(BYTES) CNT
FROM DBA_FREE_SPACE
GROUP BY TABLESPACE_NAME
UNION
SELECT TABLESPACE_NAME,SUM(BYTES) TOTAL1,0,0,0
FROM DBA_DATA_FILES
GROUP BY TABLESPACE_NAME) A
GROUP BY A.TABLESPACE_NAME
ORDER BY TABLESPACE;
// 전체 합처리
SELECT ROUND(SUM(A.TOTAL1)/1024/1024/1024,1) "TOTALGB",
ROUND(SUM(A.TOTAL1)/1024/1024/1024,1)-ROUND(SUM(A.SUM1)/1024/1024/1024,1) "USEDGB",
ROUND(SUM(A.SUM1)/1024/1024/1024,1) "FREEGB",
ROUND((ROUND(SUM(A.TOTAL1)/1024/1024,1)-ROUND(SUM(A.SUM1)/1024/1024,1))
/ROUND(SUM(A.TOTAL1)/1024/1024,1)*100,2) "USED%"
FROM
(SELECT TABLESPACE_NAME,0 TOTAL1,SUM(BYTES) SUM1,MAX(BYTES) MAXB,
COUNT(BYTES) CNT
FROM DBA_FREE_SPACE
GROUP BY TABLESPACE_NAME
UNION
SELECT TABLESPACE_NAME,SUM(BYTES) TOTAL1,0,0,0
FROM DBA_DATA_FILES
GROUP BY TABLESPACE_NAME) A
'Database / Sql' 카테고리의 다른 글
[Oracle] IO를 많이 발생시키는 쿼리 찾기 (0) | 2014.09.02 |
---|---|
[Oracle] 각 테이블/인덱스 사이즈 조회 쿼리 (0) | 2014.03.06 |
[Oracle] SID, SPID 를 통해 수행하고 있는 쿼리 찾기 (0) | 2013.11.27 |
[Oracle] SYS_CONNECT_BY_PATH 문자열 합치기?? (0) | 2013.10.18 |
[Oracle] 대소문자 처리 (0) | 2013.09.26 |