-- // 옵티마이저가 인덱스를 사용하지 못하게 변경
ALTER TABLE employees ALTER INDEX ix_hiredate INVISIBLE;
-- // 옵티마이저가 인덱스를 사용할 수 있게 변경
ALTER TABLE employees ALTER INDEX ix_hiredate VISIBLE;
use_invisible_indexes 옵티마이저 옵션을 이용하면 INVISIBLE로 설정된 인덱스도 옵티마이저가 사용할 수 있게할 수 있다.
INVISIBLE 인덱스는 사용하지 않는다.-- // 현제 세션에서 인덱스 스킵 스캔 활성화
SET optimizer_switch='skip_can=on';
-- // 특정 테이블에 대해 인덱스 스킵 스캔을 사용하도록 힌트 사용
SELECT /*+ SKIP_SCAN(employees)*/ COUNT(*)
FROM employees
WHERE birth_date>='1965-02-01';
-- // 특정 테이블에 대해 인덱스 스킵 스캔을 사용하지 않도록 힌트 사용
SELECT /*+ NO_SKIP_SCAN(employees)*/ COUNT(*)
FROM employees
WHERE birth_date>='1965-02-01';
ORDER BY 또는 GROUP BY를 인덱스로 처리 가능한 경우 실행 계획에서 이 인덱스 가중치를 높이 설정해서 실행된다.EXPLAIN SELECT *
FROM employees
WHERE hire_date BETWEEN '1995-01-01' AND '1995-02-01'
ORDER BY emp_no;
ix_hiredate 인덱스로 WHERE 조건절에 해당하는 레코드를 찾은 다음 emp_no로 정렬해서 결과를 반환employees 테이블의 프라이머리 키가 emp_no이므로 프라이머리 키를 정순으로 읽으면서 WHERE 조건에 일치하는지 비교 후 결과 반환hire_date 칼럼의 조건에 부합되는 레코드 수가 적다면 1번이 효율적이다.
employees의 전체 레코드 수가 많다면 2번 방법으로 모든 레코드를 읽는 것은 비효율적이다.IGNORE INDEX 힌트를 사용했다.ORDER BY를 위한 인덱스에 너무 가중치를 부여하지 않도록 prefer_ordering_index 옵티마이저 옵션이 추가되었다.-- // 현재 커넥션에서만 비활성화
SET SESSION optimizer_switch='prefer_ordering_index=OFF';
-- // 현재 쿼리에 대해서만 비활성화
SELECT /*+ SET_VAR(optimizer_switch='prefer_ordering_index=OFF') */
...
FROM
...