힌트는 일종의 지시문이다. SQL 문장에 힌트를 추가하여Tibero의 질의 최적화기(Optimizer)에 특정 행동을 지시하거나질의 최적화기의 실행 계획을 변경한다. 질의 최적화기가 항상 최적의 실행 계획을 수립할 수는 없다. 따라서 개발자가 질의 최적화기의 실행 계획을 직접 수정할 수 있는 방법을 마련한 것이 바로 힌트이다.
SQL 문장의 한 블록당 힌트는 하나만 올 수 있으며, SELECT, UPDATE, INSERT, DELETE 절 바로 뒤에위치해야 한다.
다음은 힌트를 사용한 예이다.
(DELETE|INSERT|SELECT|UPDATE) /*+ hint [hint] ... */
또는
(DELETE|INSERT|SELECT|UPDATE) --+ hint [hint] ...
(예) SELECT /*+ 힌트명 */ T2.FK, T2.A FROM T1, T2 WHERE T2.FK = T1.PK
SELECT --+ 힌트명 T2.FK, T2.A FROM T1, T2 WHERE T2.FK = T1.PK
힌트를 사용할 때 주의할 점은 다음과 같다.
힌트는 반드시 DELETE, INSERT, SELECT, UPDATE 절 뒤에만 올 수 있다.
'+' 기호는 반드시 주석 구분자('/*' 또는 '--') 바로 뒤에 공백 없이 붙여 써야 한다.
힌트와 '+' 기호 사이에 공백은 있어도 되고, 없어도 된다.
문법에 맞지 않는 힌트는 주석으로 취급되며, 에러는 발생하지 않는다.
[ 힌트의 종류 ]
질의 변형
NO_QUERY_TRANSFORMATION
질의 변형기에게 전체 쿼리에 대해서 변형을 실행하지 않도록 지시한다.
NO_MERGE
질의 변형기에게 특정 뷰에 대한 뷰 병합(View Merging)을 하지 않도록 지시한다.
UNNEST
질의 변형기에게 특정 부질의를 언네스팅(Unnesting)하도록 지시한다.
NO_UNNEST
질의 변형기에게 특정 부질의에 대해 언네스팅을 수행하지 않도록 지시한다.
NO_JOIN_ELIMINATION
질의 변형기에게 조인 제거를 수행하지 않도록 지시한다.
STAR_TRANSFORMATION
질의 변형기에게 스타 변형(Star Transformation)을 하도록 지시한다.
최적화 방법
ALL_ROWS
전체 결과에 대한 처리량이 가장 많도록 처리과정의 최적화를 선택한다.
FIRST_ROWS
결과를 가장 빠르게 보여줄 수 있도록 결과 표시의 최적화를 선택한다.
접근 방법
FULL
전체 테이블을 스캔하도록 지시한다.
INDEX
명시한 인덱스를 사용한 인덱스 스캔을 하도록 지시한다.
NO_INDEX
명시한 인덱스를 사용한 인덱스 스캔을 하지 않도록 지시한다.
INDEX_ASC
명시한 인덱스를 사용한 인덱스 스캔을 오름차순으로 하도록 지시한다.
INDEX_DESC
명시한 인덱스를 사용한 인덱스 스캔을 내림차순으로 하도록 지시한다.
INDEX_FFS
명시한 인덱스를 사용한 인덱스를 사용해 빠른 전체 인덱스 스캔(Fast Full Index Scan)을 하도록 지시한다.
NO_INDEX_FFS
명시한 인덱스를 사용한 빠른 전체 인덱스 스캔을 하지 않도록 지시한다.
INDEX_RS
명시한 인덱스를 사용한 인덱스를 사용해 범위 인덱스 스캔(Range Index Scan)을 하도록 지시한다.
NO_INDEX_RS
명시한 인덱스를 사용한 범위 인덱스 스캔을 하지 않도록 지시한다.
INDEX_SS
명시한 인덱스를 사용한 인덱스를 사용해 인덱스 스킵 스캔(Index Skip Scan)을 하도록 지시한다.
NO_INDEX_SS
명시한 인덱스를 사용한 인덱스 스킵 스캔을 하지 않도록 지시한다.
INDEX_JOIN
명시한 테이블에 두 개 이상의 인덱스를 사용하여 자체 조인(Self Join)하도록 지시한다.
조인 순서
LEADING
먼저 조인되어야 할 테이블의 집합을 명시한다.
ORDERED
테이블을 FROM 절에 명시된 순서대로 조인하도록 지시한다.
조인 방법
USE_NL
중첩 루프 조인을 사용하도록 지시한다.
NO_USE_NL
중첩 루프 조인을 사용하지 않도록 지시한다.
USE_NL_WITH_INDEX
명시한 인덱스와 두 테이블에 대한 조인 조건을 이용해 중첩 루프 조인을 사용하도록 지시한다.
USE_MERGE
합병 조인을 사용하도록 지시한다.
NO_USE_MERGE
합병 조인을 사용하지 않도록 지시한다.
USE_HASH
해시 조인을 사용하도록 지시한다.
NO_USE_HASH
해시 조인을 사용하지 않도록 지시한다.
HASH_SJ
부질의를 언네스팅할 때 해시방법을 이용한 세미조인으로 하도록 지시한다.
HASH_AJ
부질의를 언네스팅할 때 해시방법을 이용한 안티조인으로 하도록 지시한다.
MERGE_SJ
부질의를 언네스팅할 때 머지방법을 이용한 세미조인으로 하도록 지시한다.
MERGE_AJ
부질의를 언네스팅할 때 머지방법을 이용한 안티조인으로 하도록 지시한다.
NL_SJ
부질의를 언네스팅할 때 네스티드 룹 방법을 이용한 세미조인으로 하도록 지시한다.
NL_AJ
부질의를 언네스팅할 때 네스티드 룹 방법을 이용한 안티조인으로 하도록 지시한다.
SWAP_JOIN_INPUTS
해시 조인을 수행하는 경우 빌드 테이블이 되도록 지시한다.
NO_SWAP_JOIN_INPUTS
해시 조인을 수행하는 경우 조인 순서가 변경되지 않도록 지시한다.
병렬 처리
PARALLEL
지정한 개수의 스레드를 사용해 질의의 수행을 병렬로 진행하도록 지시한다.
NO_PARALLEL
질의의 수행을 병렬로 진행하지 않도록 지시한다.
PQ_DISTRIBUTE
조인을 포함한 질의의 병렬 처리에서 로우의 분산 방법을 지시한다.
실체화 뷰
REWRITE
비용의 비교 없이 실체화 뷰(Materialized View)를 사용하여 질의의 다시 쓰기를 지시한다.
NO_REWRITE
질의의 다시 쓰기를 하지 않도록 지시한다.
MATERIALIZE
With 절 안에 있는 Subquery를 실체화 뷰(Materialized View)로 만들도록 지시한다.
INLINE
With 절 안에 있는 Subquery를 실체화 뷰(Materialized View)로 만들지 않도록 지시한다.
기타
APPEND
DML 문장에서 직접 데이터 파일에 추가하는 삽입 방법 즉 Direct-Path 방식을 수행하도록 지시한다.
APPEND_VALUES
VALUES 절을 사용하는 INSERT 문에서 직접 데이터 파일에 추가하는 삽입 방법 즉 Direct-Path 방식을 수행하도록 지시한다.
NOAPPEND
DML 문장에서 Direct-Path 방식을 수행하지 않도록 지시한다.
IGNORE_ROW_ON_DUPKEY_INDEX
유일키 제약조건을 위배하는 로우가 삽입 될 때, 에러를 발생하지 않도록 한다.
CARD
지정 테이블의 Cardinality를 지정하여, 쿼리를 최적화 할때 이용하도록 한다.
MONITOR
쿼리를 수행할 때 쿼리 수행 정보를 모으도록 지시한다.
NO_MONITOR
쿼리를 수행할 때 쿼리 수행 정보를 모으지 않도록 지시한다.
USE_CONCAT
OR expansion된 플랜만 생성한다.
NO_EXPAND
OR expansion된 플랜을 배제한다.
RESULT_CACHE
Query 결과를 저장하기 위해 Result Cache를 사용한다.
NO_SUBQUERY_CACHE
쿼리를 수행하는 경우 특정 부질의에 대해 부질의 결과를 캐싱하지 않도록 강제한다.
OPT_PARAM
쿼리가 수행되는 동안 초기화 환경 변수를 바꾸는 데 사용한다.
1. 질의 변형에 대한 힌트
질의 변형(Query Transformation)에 대한 힌트를 사용하여Tibero의 질의 변형 방식에 영향을 줄 수 있다.
NO_QUERY_TRANSFORMATION
NO_QUERY_TRANSFORMATION는 질의 변형기(Query Transformer)가 전체 쿼리에 대해 변형을 실행하지 않도록 지시하는 힌트이다.Tibero에서는 쿼리 변형이 자동으로 수행되며, 최적화된 형태로 쿼리를 변형하여 실행계획을 생성하다. NO_QUERY_TRANSFORMATION 힌트를 사용한다면 디폴트로 수행되는 쿼리 변형을 막을 수 있다.
문법
(예제 )
SELECT /*+NO_QUERY_TRANSFORMATION */ T2.FK, T2.A
FROM T1, T2
WHERE T2.FK = T1.PK
NO_MERGE
NO_MERGE는 질의 변형기(Query Transformer)가 특정 뷰에 대해 뷰 병합을 하지 않도록 지시하는 힌트이다.Tibero에서는 뷰 병합이 디폴트로 수행되며, 뷰가 병합이 가능할 경우 상위의 질의 블록과 결합해 하나의 질의 블록을 형성한다. NO_MERGE 힌트를 사용하면 이렇게 디폴트로 수행되는 뷰의 병합을 막을 수 있다.
문법
위의 예에서처럼 NO_MERGE 힌트는 병합되기를 원하지 않는 뷰의 질의 블록에 명시한다. 힌트가 없었다면 뷰가 병합되어 질의 최적화기에서 테이블 T1, T2, T3에 대한 조인 순서와 조인 방법을 고려하게 되지만, 위와 같이 힌트가 있을 경우는 뷰가 병합되지 못하기 때문에 T2와 T3가 먼저 조인되고, 그 이후에 T1이 조인된다.
(예제 )
SELECT * FROM T1, (SELECT /*+ NO_MERGE */ * FROM T2, T3 WHERE T2.A = T3.B) V WHERE T1.C = V.D
UNNEST
UNNEST는 질의 변형기가 특정 부질의(Subquery)를 언네스팅하도록 지시하는 힌트이다.Tibero는 부질의 언네스팅을 디폴트로 수행하지만, 특정 쿼리만 언네스팅을 하려면 초기화 파라미터에서 언네스팅을 해제하면 된다. 그러면 UNNEST 힌트를 이용할 수 있다. UNNEST 힌트는 부질의 블록에 명시한다.
문법
NO_UNNEST
NO_UNNEST는 질의 변형기가 특정 부질의에 대해 언네스팅을 수행하지 않도록 지시하는 힌트이다.Tibero는 부질의 언네스팅을 디폴트로 수행하며 언네스팅이 가능한 경우 부질의를 조인으로 변환한다. 이때 NO_UNNEST 힌트를 사용해서 언네스팅을 막을 수 있다. NO_UNNEST 힌트는 부질의 블록에 명시한다.
문법
NO_JOIN_ELIMINATION
NO_JOIN_ELIMINATION는 질의 변형기(Query Transformer)가 불필요한 조인을 찾아서 제거하지 않도록 지시하는 힌트이다. Tibero에서는 디폴트로 질의 결과를 생성하는데 필요하지 않은 조인들을 찾아서 제거하며, NO_JOIN_ELIMINATION 힌트를 사용하면 이를 막을 수 있다.
문법위의 예처럼 T2의 컬럼을 요청하였을 때 T1과 T2 사이에 참조 관계가 정의되어 있다면 T1과 조인을 하지 않아도 조건절에 주어진 T2.FK = T1.PK는 T2.FK가 NULL이 아닌 한 참임을 알 수 있다. 질의 변환기는 이처럼 필요하지 않은 조인을 찾아 제거하는데 NO_JOIN_ELIMINATION 힌트를 적용하면 이러한 기능을 막을 수 있다
(예제 )
SELECT /*+ NO_JOIN_ELIMINATION */ T2.FK, T2.A FROM T1, T2 WHERE T2.FK = T1.PK
반응형
STAR_TRANSFORMATION
STAR_TRANSFORMATION는 스타 변형 (STAR TRANSFORMATION)이 가능할 경우 변형을 시도하도록 지시하는 힌트이다. Tibero에서는 디폴트로 스타 변형을 하지않도록 하는데, STAR_TRANSFORMATION 힌트를 사용하면 이를 사용할 수 있다.
문법
스타 스키마(STAR SCHEMA)를 사용하는 데이터 베이스 환경에서 위의 예처럼 쿼리를 쓰면 스타 변형을 할 수 있다. 이 변형은 기존 INDEX JOIN으로만 풀린 플랜에서 BITMAP KEY ITERATION을 포함한 플랜으로 풀리게 하여 더 효율적인 결과를 얻게 한다.
(예제)
SELECT /*+ STAR_TRANSFORMATION */ s.* FROM S, T1, T2 WHERE S.C1 = T1.C1 AND S.C2 = T2.C2
2. 최적화 방법 적용된 힌트
최적화 방법이 적용된 힌트를 사용하여 처리 과정과 결과 표시를 최적화할 수 있다. 만약 최적화 방법이 적용된 힌트가 사용된 질의가 있다면 해당 질의에 대해서는 통계 정보와 초기화 파라미터의 최적화 방법(OPTIMIZER MODE)의 값이 없는 것처럼 처리된다.
ALL_ROWS
ALL_ROWS는 최소한의 리소스를 사용하여 전체 결과에 대한 처리량이 가장 많도록 처리과정의 최적화 방법을 선택하는 힌트이다.
문법
(예제) SELECT /*+ ALL_ROWS */ S.* FROM S, T1, T2 WHERE S.C1 = T1.C1 AND S.C2 = T2.C2
FIRST_ROWS
FIRST_ROWS는 첫 로우부터 파라미터로 입력된 번호의 로우까지 가장 빠르게 보여줄 수 있도록 결과 표시의 최적화 방법을 선택하는 힌트이다.
문법 (예제) SELECT /*+ FIRST_ROWS */ S.* FROM S, T1, T2 WHERE S.C1 = T1.C1 AND S.C2 = T2.C2
3. 접근 방법이 적용된 힌트
접근 방법이 적용된 힌트는 질의 최적화기가 특정 접근 방법의 사용이 가능한 경우, 그 방법을 사용하도록 명시한다. 만일 힌트에서 명시한 방법을 사용할 수 없는 경우에는 질의 최적화기는 그 힌트를 무시한다.
힌트에 명시하는 테이블명은 SQL 문에서 사용하는 이름과 동일해야 한다. 즉, 테이블 이름에 대한 별칭을 사용하였다면, 테이블 이름 대신에 별칭을 사용하여야 한다. SQL 문에서 테이블 이름에 스키마 이름을 포함하여 명시하였더라도 힌트에서는 테이블 이름만을 명시하여야 한다.
FULL
FULL은 명시한 테이블을 스캔할 때, 전체 테이블을 스캔하도록 지시하는 힌트이다. WHERE 절에 명시된 조건식에 맞는 인덱스가 있더라도 전체 테이블 스캔을 사용한다.
문법
INDEX
INDEX는 명시한 테이블을 스캔할 때, 명시한 인덱스를 사용하여 인덱스 스캔을 하도록 지시하는 힌트이다.
문법
NO_INDEX
NO_INDEX는 명시한 테이블을 스캔할 때, 명시한 인덱스를 사용하는 인덱스 스캔을 하지 않도록 지시하는 힌트이다. 만일 NO_INDEX 힌트와 INDEX 또는 INDEX_ASC, INDEX_DESC 힌트가 동일한 인덱스를 명시한다면 질의 최적화기는 이 두 힌트를 모두 무시한다.
문법
INDEX_ASC
INDEX_ASC는 명시한 테이블을 스캔할 때, 명시한 인덱스를 사용하여 인덱스 스캔을 하도록 지시하는 힌트이다. 만일 인덱스 범위 스캔을 사용하는 경우에는 인덱스를 오름차순으로 스캔하도록 한다. 현재Tibero의 인덱스 스캔의 기본 동작이 오름차순이기 때문에 INDEX_ASC는 INDEX와 동일한 작업을 수행한다. 분할된 인덱스의 경우 분할된 각 영역 내에서 오름차순으로 스캔한다.
문법
INDEX_DESC
INDEX_DESC는 명시한 테이블을 스캔할 때, 명시한 인덱스를 사용하여 인덱스 스캔을 하도록 지시하는 힌트이다. 만일 인덱스 범위 스캔을 사용하는 경우에는 인덱스를 내림차순으로 스캔하도록 한다. 분할된 인덱스의 경우 분할된 각 영역 내에서 내림차순으로 스캔한다.
문법
INDEX_FFS
INDEX_FFS는 명시한 테이블에 대해 명시한 인덱스를 사용하여 빠른 전체 인덱스 스캔(Fast Full Index Scan)을 사용하도록 지시하는 힌트이다.
문법
NO_INDEX_FFS
NO_INDEX_FFS는 명시한 테이블에 대해 명시한 인덱스를 사용하는 빠른 전체 인덱스 스캔을 사용하지 않도록 지시하는 힌트이다.
문법
INDEX_RS
INDEX_RS는 명시한 테이블에 대해 명시한 인덱스를 사용하여 범위 인덱스 스캔(Range Index Scan)을 사용하도록 지시하는 힌트이다.
문법
NO_INDEX_RS
NO_INDEX_RS는 명시한 테이블에 대해 명시한 인덱스를 사용하는 범위 인덱스 스캔을 사용하지 않도록 지시하는 힌트이다.
문법
INDEX_SS
INDEX_SS는 명시한 테이블에 대해 명시한 인덱스를 사용하여 인덱스 스킵 스캔(Index Skip Scan)을 사용하도록 지시하는 힌트이다.
문법
NO_INDEX_SS
NO_INDEX_SS는 명시한 테이블에 대해 명시한 인덱스를 사용하는 인덱스 스킵 스캔을 사용하지 않도록 지시하는 힌트이다.
문법
INDEX_JOIN
INDEX_JOIN은 명시한 테이블에 대해 명시한 두 개 이상의 힌트를 사용하여, 테이블을 스캔할 때 자체 조인(Self Join)을 사용하도록 지시하는 힌트이다.