TIBERO INDEX JOIN

INDEX JOIN

: 명시한 테이블에 두 개 이상의 인덱스를 사용하여 자체 조인하는 것이다.

TIBERO ( ORACLE DB 또한) 지원하는 좋은 기능이다.

하지만 보통 INDEX JOIN 처리된 각각의 집합을 HASH JOIN 처리하므로,

보편적인 OLTP SQL 3초 이내 응답기준을 만족시키기는 어렵다.

FTS( Full Table Scan ) 처리보다는 빠르게 출력되는 경우가 있지만, 어차피 서비스 응답 기준에 미치지 못한다.

그래서인지 TIBERO DB 차세대 프로젝트에서는 INDEX_JOIN 되는 PARAMETER는 비활성화 처리한다고 한다. ( 디폴트값 : YES )

Parameter : _OPT_BUILD_INDEX_FFS_SELF_JOIN

테스트가 필요하면 아래 1번을 수행하거나, 2번과 같이 SQL에 힌트를 넣고 SQL실행계획을 확인하면 된다.

1. Session level Index Join 비활성화

- ALTER SESSION SET "_OPT_BUILD_INDEX_FFS_SELF_JOIN" = FALSE;

2. Sql level Index Join 비활성화

- Hint : /*+ NO_INDEX_JOIN( TABLE ALIAS ) */ -- sql level 비활성화

위 1번 수행후에도 INDEX JOIN이 된다면 TIBERO측에 문의하여 해당 관련 파라미터 PATCH를 받아야 한다.

 

[ SQL ]
 SELECT COUNT(*) 
  FROM HR.TB_TIBERO A
WHERE A.COL1 = :1
   AND A.COL2 = :2
   AND A.COL3 = :3
   AND A.COL4 = :4
   AND A.COL5 = :5;

[ TABLE ]
 HR.TB_TIBERO : 792,592 Blocks

[ INDEX ]
TB_TIBERO_PK : COL4, COL1, COL9, COL10
TB_TIBERO_IDX01 : COL2, COL6, COL7, COL8

[ 튜닝 전 - INDEX JOIN 실행 플랜 ]
--------------------------------------------------------------------------------------------------------------------------------------
| ID  | Operation               | Name            | Cost (%CPU)  | Cards   | Rows    | Elaps. Time  | CR Gets  | Starts   | Used Mem | 
--------------------------------------------------------------------------------------------------------------------------------------
|   1 | COLUMN PROJECTION       |                 | 4580    (.07)|       1 |       1 |00:00:00.0000 |       0  |       1  |       0K | 
|   2 |  SORT AGGR              |                 | 4580    (.07)|       1 |       1 |00:00:00.0000 |       0  |       1  |      67K | 
|   3 |   TABLE ACCESS (ROWID)  | TB_TIBERO       | 4580    (.07)|       1 |       0 |00:00:01.8682 |    1065  |       1  |       0K | 
|   4 |    HASH JOIN            |                 | 1949    (.15)|    2630 |   39733 |00:00:00.9873 |       0  |       1  |      84M | 
|   5 |     INDEX (RANGE SCAN)  | TB_TIBERO_PK    |  631      (0)|  110528 |  631620 |00:00:05.5036 |    5695  |       1  |       0K | 
|   6 |     INDEX (RANGE SCAN)  | TB_TIBERO_IDX01 | 1315      (0)|  457766 | 1612482 |00:00:19.9599 |    6157  |       1  |       0K | 
--------------------------------------------------------------------------------------------------------------------------------------

[ 튜닝 전 - FULL SCAN ]
-------------------------------------------------------------------------------------------------------------------------------
| ID  | Operation              | Name      | Cost (%CPU)  | Cards   | Rows    | Elaps. Time  | CR Gets  | Starts   | Used Mem |
------------------------------------------------------------------------------------------------------------------------------
|   1 | COLUMN PROJECTION      |           |  328K   (.13)|       1 |       1 |00:00:00.0000 |       0  |       1  |       0K |
|   2 |  SORT AGGR             |           |  328K   (.13)|       1 |       1 |00:00:00.0000 |       0  |       1  |      67K |
|   3 |   TABLE ACCESS (FULL)  | TB_TIBERO |  328K   (.13)|       1 |       0 |00:03:50.4085 |     855K |       1  |       0K |
-------------------------------------------------------------------------------------------------------------------------------

[ 튜닝 후 - 타 인덱스 이용 ]
-----------------------------------------------------------------------------------------------------------------------------------------
| ID  | Operation               | Name               | Cost (%CPU)  | Cards   | Rows    | Elaps. Time  | CR Gets  | Starts   | Used Mem |
-----------------------------------------------------------------------------------------------------------------------------------------
|   1 | COLUMN PROJECTION       |                    |   89      (0)|       1 |       1 |00:00:00.0000 |       0  |       1  |       0K |
|   2 |  SORT AGGR              |                    |   89      (0)|       1 |       1 |00:00:00.0000 |       0  |       1  |      67K |
|   3 |   TABLE ACCESS (ROWID)  | TB_TIBERO          |   89      (0)|       1 |       0 |00:00:00.0001 |       5  |       1  |       0K |
|   4 |    INDEX (SKIP SCAN)    | TB_TIBERO_IDX02    |   79      (0)|     292 |       8 |00:00:00.0003 |      18  |       1  |       0K |
-----------------------------------------------------------------------------------------------------------------------------------------

[ 분석 ]
FTS(Full Table Scan)으로 855,000 Block을 읽는 것보다는 INDEX JOIN 처리한 것이 상대적으로 적은 약 12,000 Block으로 
읽었고, 응답시간이 빨랐다. 하지만 INDEX SCAN 마다 범위가 넓고 도출된 ROW 또한 많아 응답시간이 매우 느려졌다. 
이 응답시간으로는 어플리케이션 서비스는 불가능하다. 
( INDEX JOIN이 되면 최적의 INDEX ACCESS 조건을 제공하는 것은 어렵다. )
해당 기능은 OLTP 보다는 BATCH 쪽에 그나마 좋을 것 같은데 개인적으로는 배치에서도 대체할 기능들이 많기에 
INDEX JOIN 활용은 불필요해 보인다. 

그럼에도 불구하고 보편적으로 SQL 응답시간에 도움을 주는 기능인 것은 맞다.

돈 없으면 몸으로라도 때워 느낌이다. 
( 적당한 INDEX 없고, FULL SCAN도 하기 힘들면 INDEX JOIN으로라도 때워 )
그냥 돈 없으면 배째...

-------------------
2023.09.06
 적은 BLOCK을 보유한 INDEX FAST FULL SCAN 들로 INDEX JOIN시 BLOCK을 획기적으로 줄일수 있다. 
 TABLE BLOCK은 많고, 인덱스 구성하기는 힘들시 차선책..
 위에 언급한 바와 같이 적합한 ACCESS 조건이 없어 추출 ROW 많음.
 그 결과 HASH JOIN 처리량과 메모리 사용량 많음.
 FTS or INDEX JOIN or 인덱스 신규/변경 중 합리적으로 따져 선택!
[ 예시 ]
  15 |    HASH JOIN                    |                             | 1434    (.35)|  494171 |  576879 |00:00:01.1799 |       0  |       1  |      55M |         0  |         0  |
  16 |     INDEX (FAST FULL SCAN)      | PK_                         |  635      (0)|  661551 |  844173 |00:00:00.0222 |    1883  |       1  |       0K |         0  |         0  |
  17 |     INDEX (FAST FULL SCAN)      | CU001                       |  794      (0)|  661551 |  844172 |00:00:00.0254 |    2811  |       1  |       0K |         0  |         0 
​