옵티마이저 스위치: 스킵 스캔

공부하는 감자·2024년 3월 31일
0

MySQL

목록 보기
37/74
post-thumbnail

스킵 스캔

인덱스의 제약 사항

  • 인덱스의 핵심은 값이 정렬되어 있다는 것이며, 이로 인해 인덱스를 구성하는 칼럼의 순서는 매우 중요하다.
  • 만약 (A, B, C) 칼럼으로 구성된 인덱스가 있을 때, WHERE 절에 B와 C 칼럼에 대한 조건을 가지고 있다면 이 쿼리는 인덱스를 활용할 수 없다는 제약이 있다.
    • 인덱스를 활용하려면 A 칼럼에 대한 조건이 필수적이다.
    • A → B → C 순으로 정렬되기 때문

Skip Scan

  • MySQL 8.0 버전부터 도입되었다.
  • 인덱스 스킵 스캔은 제한적이긴 하지만 인덱스의 제약 사항을 뛰어넘을 수 있는 최적화 기법이다.
  • 인덱스의 선행 칼럼이 조건절에 사용되지 않더라도 후행 칼럼의 조건만으로 인덱스를 이용한 쿼리 성능 개선이 가능하다.
    • 테이블에 존재하는 모든 선행 칼럼을 값을 가져와 두 번째 쿼리와 같이 선행 칼럼의 조건이 있는 것처럼 쿼리를 최적화한다.
  • 인덱스의 선행 칼럼이 매우 다양한 값을 가지는 경우에는 인덱스 스킵 스캔 최적화가 비효율적일 수 있다.
    • MySQL 8.0 옵티마이저는 인덱스의 선행 칼럼이 소수의 유니크한 값을 가질 때만 인덱스 스킵 스캔 최적화를 사용한다.
    • 앞선 B-Tree-인덱스의 ‘인덱스 스킵 스캔’ 파트 참조
  • 다음과 같이 활성화 여부를 제어할 수 있다.
    -- 현재 세션에서 인덱스 스킵 스캔 최적화을 활성화
    SET optimizer_switch='skip_scan=on';
    
    -- 현재 세션에서 인덱스 스킵 스캔 최적화를 비활성화
    SET optimizer_switch='skip_scan=off';
    
    -- 특정 테이블에 대해 인덱스 스킵 스캔을 사용하도록 힌트를 사용
    SELECT /*+ SKIP_SCAN(employees)*/ COUNT(*)
    FROM employees
    WHERE birth_date >= '1965-02-01';
    
    -- 특정 테이블과 인덱스에 대해 인덱스 스킵 스캔을 사용하도록 힌트를 사용
    SELECT /*+ SKIP_SCAN(employees ix_gender_birthdate)*/ COUNT(*)
    FROM employees
    WHERE birth_date >= '1965-02-01';
    
    -- 특정 테이블에 대해 인덱스 스킵 스캔을 사용하지 않도록 힌트를 사용
    SELECT /*+ NO_SKIP_SCAN(employees)*/ COUNT(*)
    FROM employees
    WHERE birth_date >= '1965-02-01';

Reference

참고 서적

📔 Real MySQL 8.0

profile
책을 읽거나 강의를 들으며 공부한 내용을 정리합니다. 가끔 개발하는데 있었던 이슈도 올립니다.

0개의 댓글