질문 :
아래 쿼리A 와 쿼리B의 차이점은 YYYYMM_INV 컬럼 조건절에서 ||'' 가 붙느냐 안붙느냐 뿐인데
그로인해 실행계획이 달라져버립니다ㅠㅠ
||'' 가 무슨 역할을 하는지 모르겠어요..
검색해도 나오지 않아 질문 드립니다ㅠ
<쿼리 A>
SELECT *
FROM IEBL_PROD_USE_AMT
WHERE YYYYMM_INV || '' = '201501'
AND ID_ACCT = '1000458053'
AND ID_SO = '2100'
AND FG_INV = '01'
AND CD_RSLT = '30';
Execution Plan
-----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=3 Card=1 Bytes=208)
1 0 TABLE ACCESS (BY GLOBAL INDEX ROWID) OF 'IEBL_PROD_USE_AMT' (Cost=3 Card=1 Bytes=208)
2 1 INDEX (RANGE SCAN) OF 'IEBL_PROD_USE_AMT_IDX6' (NON-UNIQUE) (Cost=4 Card=1)
-----------------------------------------------------------
<쿼리 B>
SELECT *
FROM IEBL_PROD_USE_AMT
WHERE YYYYMM_INV = '201501'
AND ID_ACCT = '1000458053'
AND ID_SO = '2100'
AND FG_INV = '01'
AND CD_RSLT = '30';
Execution Plan
-----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=245 Card=7 Bytes=1K)
1 0 TABLE ACCESS (FULL) OF 'IEBL_PROD_USE_AMT' (Cost=245 Card=7 Bytes=1K)
-----------------------------------------------------------
<테이블 정보>
Table Partition
-----------------------------------------------------------------------------
Type = Range Partition
Keys = ID_SO,YYYYMM_INV
<인덱스 정보>
INDEX
-----------------------------------------------------------------------------
IEBL_PROD_USE_AMT_IDX6 : ID_ACCT,YYYYMM_INV,FG_INV,ID_SO,AMT_UNPMT
글로벌 인덱스는 파티션 키와는 다른 결합의 인덱스일때 사용하는거구요.
이걸 만들어 놓으면 파티션별 테이블 작업을 하게 될 때
글로벌 인덱스가 언유저블로 빠지게 되어 리빌드를 해줘야만 하는 상황이 발생됩니다.
하지만 로컬인덱스는 해당 파티션에만 영향을 받으므로 리빌드할 필요도 없구요.
파티션 키를 포함하는 인덱스를 굳이 글로벌로 만들어 위험을 자초할 필요가 없구요.
위에서도 글로벌 인덱스를 만들었지만 제대로 타질 않고 파티션풀스캔을 했구요.
이부분은 옵티마이저가 판단미스를 한게 아닐까도 생각이 들구요.
파티션 키에 억지로 가공을 하여 글로벌 인덱스를 타게 했지만.
인덱스의 두번째 항목이 가공되어 인덱스 엑세스는 첫번쨰 컬럼만으로 이루어지게되어
인덱스를 탄 효과가 적을 듯 하네요.
로컬 인덱스로 만들었다면 아무 문제가 없었지 않았을까 생각됩니다.