SELECT
키워드로 시작하는 서브 쿼리 영역을 쿼리 블록이라고 한다.EXPLAIN
SELECT /*+ INDEX(employees ix_firstname) */ *
FROM employees
WHERE first_name='Matt''
ERROR 3024 (HY000): Query execution was interrupted, maximum statement execution time exceeded
SELECT /*+ MAX_EXECUTION_TIME(100) */ *
FROM employees
ORDER BY last_name LIMIT 1;
SET_VAR
힌트를 통해 optimizer_switch
시스템 변수를 제어해야할 수도 있다.SELECT /*+ SET_VAR(optimizer_switch='index_merge_intersection=off') */ *
FROM employees
WHERE first_name='Georgi' AND emp_no BETWEEN 10000 AND 20000;
SEMIJOIN
힌트는 세미 조인 최적화의 어떤 세부 전략을 사용할지를 제어할 수 있게 해준다.
NO_SEMIJOIN
힌트도 제공되는 것이다.최적화 전략 | 힌트 |
---|---|
Duplicate Weed-out | SEMIJOIN(DUPSWEEDOUT) |
First Match | SEMIJOIN(FIRSTMATCH) |
Loose Scan | SEMIJOIN(LOSSESCAN) |
Materialization | SEMIJOIN(MATERIALZATION) |
Table Pull-out | 없음 |
SELECT * FROM departments d
WHERE d.dept_no IN
(SELECT /*+ SEMIJOIN(MATERIALIZATION) */ de.dept_no
FROM dept_emp de);
최적화 방법 | 힌트 |
---|---|
IN-to-EXISTS | SUBQUERY(INTOEXISTS) |
Materialization | SUBQUERY(MATERIALIZATION) |
IN(subquery)
형태의 쿼리에 사용될 수 있지만 안티 세미 조인 최적화에는 사용될 수 없다.BNL
힌트를 사용하면 해시 조인을 사용하도록 유도하는 힌트로 용도가 변경되었다.HASHJOIN
과 NO_HASHJOIN
힌트는 8.0.18 버전에서만 유효하며 그 이후 버전에서는 효력이 없다.BNL
과 NO_BNL
힌트를 사용해야 한다.STRAIGHT_JOIN
힌트를 사용하면 FROM
절에 명시된 테이블 순서대로 조인 순서를 조정할 수 있지만 일부는 조인 순서를 강제하고 일부는 옵티마이저에게 순서를 결정하게 맡기는 것이 불가능했다.JOIN_FIXED_ORDER
: STRAIGHT_JOIN
힌트와 동일한 기능JOIN_ORDER
: 힌트에 명시된 테이블 순서대로 조인을 실행하는 힌트JOIN_PREFIX
: 조인에서 드라이빙 테이블만 강제하는 힌트JOIN_SUFFIX
: 조인에서 가장 마지막에 조인돼야 할 드리븐 테이블만 강제하는 힌트-- // FROM 절에 명시된 순서대로 조인
SELECT /*+ JOIN_FIXED_ORDER() */ *
FROM employees e
INNER JOIN dept_emp de ON de.emp_no=e.emp_no
INNER JOIN departments d ON d.dept_no=de.dept_no;
-- // 일부 테이블에 대해서만 조인 순서를 나열
SELECT /*+ JOIN_ORDER(d, de) */ *
FROM employees e
INNER JOIN dept_emp de ON de.emp_no=e.emp_no
INNER JOIN departments d ON d.dept_no=de.dept_no;
-- // 조인의 드라이빙 테이블에 대해서만 조인 순서 나열
SELECT /*+ JOIN_PREFIX(e, de) */ *
FROM employees e
INNER JOIN dept_emp de ON de.emp_no=e.emp_no
INNER JOIN departments d ON d.dept_no=de.dept_no;
-- // 조인의 드리븐 테이블에 대해서만 조인 순서 나열
SELECT /*+ JOIN_SIFFIX(de, e) */ *
FROM employees e
INNER JOIN dept_emp de ON de.emp_no=e.emp_no
INNER JOIN departments d ON d.dept_no=de.dept_no;
FROM
절에 사용된 서브 쿼리는 내부 임시 테이블(파생 테이블)을 생성할 수도 있는데 이는 불필요한 자원 소모를 유발한다.MERGE
또는 NO_MERGE
힌트를 통해 이를 제어할 수 있다.
MERGE
: 외부 쿼리와 통합NO_MERGE
: 임시 테이블 생성SELECT /*+ MERGE(sub) */ *
FROM (SELECT * FROM employees WHERE first_name='Matt') sub
LIMIT 10;
INDEX_MERGE
와 NO_INDEX_MERGE
힌트를 사용할 수 있다.SELECT /*+ NO_INDEX_MERGE(employees PRIMARY) */ *
FROM employees
WHERE first_name='Georgi' AND emp_no BETWEEN 10000 AND 20000;
NO_ICP
힌트를 통해 옵티마이저가 좀 더 유연하고 정확하게 실행 계획을 선택하게 할 수 있다.NO_SKIP_SCAN
을 사용할 수 있다.SELECT /*+ NO_SKIP_SCAN(employees ix_gender_birthdate) */ gender, birth_date
FROM employees
WHERE birth_date>='1965-02-01';
INDEX
와 NO_INDEX
옵티마이저 힌트는 예전에 사용되던 인덱스 힌트를 대체하는 용도로 제공된다.
INDEX
, GROUP_INDEX
, ORDER_INDEX
, NO_ONDEX
, NO_GROUP_INDEX
, NO_ORDER_INDEX
SELECT * /*+ INDEX(employees ix_firstname) */ *
FROM employees WHERE first_name='Matt';