특정 테이블의 특정 컬럼에서, 조건절에 의한 조회(where id=?와 같은)를 더 빠르게 만들어주는 녀석. 독자적인 공간을 차지하므로 모든 컬럼에 인덱스를 걸면 오히려 성능이 저하되며, 카디널리티가 높은(중복도가 낮은) 컬럼에 대해서 인덱스를 설정하면 조회 속도에서의 이점을 가진다.
SELECT * FROM TABLE T WHERE T.AGE + 10 = 30 // 인덱스 X
SELECT * FROM TABLE T WHERE T.AGE IS NULL
SELECT * FROM TABLE T WHERE T.AGE IS NOT NULL
SELECT * FROM TABLE T WHERE T.AGE != 30
SELECT * FROM TABLE T WHERE T.NAME LIKE '%abc' // 인덱스 X
SELECT * FROM TABLE T WHERE T.NAME LIKE 'abc%' // 인덱스 O
// 예를 들어, AGE 컬럼의 데이터가 1,2,3,4,5 라고 하자.
SELECT * FROM TABLE T WHERE T.AGE IN (1,2,3,4,5)
// 예를 들어, 복합 인덱스 순서가 name -> age 인경우
SELECT * FROM TABLE T WHERE T.AGE = 30 AND T.NAME = '춘식이' // idx X
SELECT * FROM TABLE T WHERE T.NAME = '춘식이' AND T.AGE = 30 // idx O
위 그림과 설명에 나와 있는 대로, B+ Tree 는 논리적인 트리 구조를 사용하며
조건절에서는 더블 링크드 리스트
(값(==키)에 대한 링크드 리스트와, 그 값을 가지고 있는 페이지(==포인터)에 대한 링크드 리스트)
리프 노드(맨 아래에 깔려있는 Level 0 Leaf) 에서는 싱글 링크드 리스트를 사용해서 값들을 선형으로 보관한다.
즉, 리프 노드에는 실제적 데이터가 존재 하고, 그 외 나머지 노드들에서는 리프 노드에 있는 실제 값을 찾아 갈 수 있게 해주는 논리적 데이터 가 존재한다.
인덱스는 일반적으로 B+ Tree 구조를 사용해서 데이터를 탐색한다
여러 개의 컬럼을 순서대로 인덱스화 시켜서, 단일 컬럼으로써는 카디널리티가 높지 않던 컬럼들이 결합하여 인덱스로써 활용 될 수 있다.
즉,
단일 컬럼 에서의 인덱스는 카디널리티가 충분히 높아야 사용이 "가능"하고,
결합 인덱스의 장점은 카디널리티가 높지 않은 컬럼들을 묶어서 카디널리티가 높은 것처럼 활용하여, 인덱싱 가능하다는 것이다.
그리고
결합 인덱스에서는 인덱스의 각 컬럼이 정렬되어 있으며, 이 정렬된 순서대로 데이터를 검색한다.
CREATE INDEX idx ON table_name (column_A, column_B);
@Entity
@Table(name = "table_name")
@Indexes({
@Index(name = "idx_compound", columnList = "column_A, column_B")
})
public class Entity {
// ...
}
출처 : 개발자를 위한 인덱스 생성과 SQL 작성 노하우(이병국), 참고 블로그
선행 컬럼은, 조건절로 쓰일 컬럼을 우선한다.
결합 인덱스의 컬럼 순서가
1 -> 2 -> 3 -> 4 -> 5 라면
WHERE 컬럼1 = ?
AND 컬럼2 = ?
AND 컬럼3 BETWEEN ? AND ? -- 결합인덱스에서 '='이 아닌 연산자를 사용하는 첫 번째
AND 컬럼4 = ?
AND 컬럼5 = ?
위와 같은 쿼리를 예로 들면
컬럼 1, 2, BETWEEN 연산자가 등장하는 컬럼까지는 인덱스가 활용되지만
결합 인덱스에서는 인덱스의 각 컬럼이 정렬되어 있으며, 정렬된 순서대로 데이터를 검색하므로
따라서,
결합 인덱스의 컬럼 순서를
1 -> 2 -> 4 -> 5 -> 3 으로 재정의 하는 것이 더 유리할 것.
글 재미있게 봤습니다.