Index skip scan
만약 인덱스가 (A, B)로 구성이 되어 있을 때, 선행 컬럼 A조건이 WHERE절에 없더라도 옵티마이저가 자동으로 컬럼의 유니크한 값들을 건너뛰며 후행 컬럼 B를 스캔할 수 있게 해주는 스캔 방법입니다.
예시
- 테이블: 사원
- 인덱스: (성별, 연봉)
- 쿼리:
SELECT * FROM 사원 WHERE 연봉 BETWEEN 5000 AND 7000;
일반적인 경우, 성별 조건이 없기 때문에 Index Range Scan을 하지 않습니다. 하지만 저 쿼리에서는 Index Skip Scan을 사용할 수 있습니다.
먼저 성별이 M인 구간으로 건너뛰어서 연봉이 5000~7000인 데이터를 찾습니다. 그리고 Gender가 F인 구간으로 건너 뛰어서 연봉이 5000~7000인 데이터를 찾습니다. 이건 다 인덱스가 “정렬되어 있다” 라는 성질 덕분에 가능합니다. 이렇게 되면 Full Scan 보다는 효율적이게 데이터를 뽑아올 수 있습니다.
발동 조건
하지만 Index Skip Scan이 항상 좋은 건 아닐 뿐더러, 특정 조건에서만 발동합니다. 위의 예시와 같이 선행 컬럼의 카디널리티가 낮아야합니다. 선헝 컬럼의 카디널리티가 높을 경우 Skip해야 할 구간이 너무 많아지기 때문입니다.
또, 반대로 후행 컬럼의 카디널리티가 높아야 효과적입니다.
정리
해당 스캔 방법의 장점으로는 인덱스의 개수를 줄일 수 있다와, 선행 컬럼 조건이 없는 쿼리도 인덱스를 활용해 성능을 개선할 수 있다는 겁니다.
단점으로는 발동 조건에도 적은 것처럼 선행 컬럼의 카디널리티가 높으면 성능이 저하됩니다. 명심해야하는 것이, 인덱스를 통한 스캔은 “디스크 Random I/O”가 발생하기 때문에, 자칫하면 Full Scan보다 성능이 좋지 않아집니다.
그래서 특정 조건에서만 사용해야하고, 웬만하면 선행 컬럼이 포함된 인덱스를 하나 만드는 게 좋습니다.