[MongoDB] 인덱스 교차 (인덱스 접두사 교차, 인덱스 교차 및 정렬, 인덱스 교차 및 복합 인덱스)
인덱스 교차(Intersection)란?
인덱스 교차는 MongoDB 2.6부터 제공한다.
이 용어는 인덱스의 종류가 아니라 인덱스의 작동 방식을 지칭한다.
지금까지 알아본 ‘단일 인덱스’와 ‘컴파운드 인덱스’를 하나의 컬렉션 내에서 별개로 지정하더라도 쿼리가 구동 될 때에는 내부에서 교집합처럼 동작하여 성능을 높힌다.
다음과 같이 단일 인덱스 두 가지를 선언해준다.
db.collection.createIndex({ qty: 1 })
db.collection.createIndex({ item: 1 })
단일 인덱스가 별개로 두 개를 정의했다.
db.orders.find({ item: 'abc123', qty: { $gt: 15 }})
위의 쿼리는 인덱스 교차가 적용되어 인덱스가 활용된다.
다만, 인덱스 교차는 명시적으로 선언해서 사용하는 것이 아니기 때문에 반드시 정상 동작하는지를 explain()메서드를 통해 확인해야 한다.
만약 인덱스 교차가 동작하고 있다면 결과 문서에 AND_SORTED나 AND_HASH 스테이지가 발견된다.
인덱스 접두사(index prefix) 교차
MongoDB는 전체 인덱스 또는 인덱스 접두사의 교차를 사용할 수 있다.
Index prefix는 인덱스 시작 부분에서 시작하는 하나 이상의 키로 구성된 복합 인덱스의 하위 집합이다.
* Index prefix란?
2023.03.20 - [데이터베이스/MongoDB] - [MongoDB] 접두사 인덱스, 등치 (Index Prefix, Equality)란?
[MongoDB] 접두사 인덱스, 등치 (Index Prefix, Equality)란?
[MongoDB] 접두사 인덱스, 동치 상태 (Index Prefix, Equality State)란? 인덱스 Prefix란? MongoDB의 인덱스 관련 메뉴얼을 읽다 보면 자주 나오는 용어 중에 Index Prefix라는 말이 있다. 접두사 인덱스 / 선행 인덱
kfdd6630.tistory.com
orders 컬렉션에 다음과 같은 인덱스가 있다.
{ qty: 1 }
{ status: 1, ord_date: -1 }
qty필드와 필드 모두에 대한 조건을 지정하는 다음 쿼리를 이행하기 위해 statusMongoDB는 두 인덱스의 교집합을 사용할 수 있다.
db.orders.find( { qty: { $gt: 10 } , status: "A" } )
인덱스 교차 및 정렬
sort() 작업에 쿼리 술어와 완전히 분리된 인덱스가 필요한 경우 인덱스 교차가 적용되지 않는다.
예)
orders 컬렉션에 다음과 같이 단일 인덱스들과 컴파운드 인덱스가 따로 정의되어 있다.
{ qty: 1 }
{ status: 1, ord_date: -1 }
{ status: 1 }
{ ord_date: -1 }
위 상황에서 아래의 쿼리는 정렬과 함께 인덱스 교차를 사용할 수 없다.
db.orders.find({ qty: { $gt: 10 }}).sort({ status: 1 })
그 이유는 검색 조건의 qty는 정렬조건의 status와 별개의 인덱스로 작성되었기 때문이다.
하지만 아래의 쿼리는 컴파운드 인덱스와 교차되어 정상 동작한다.
db.orders.find({ qty: { $gt: 10 }, status: "A" }).sort({ ord_date: -1 })
{ qty: 1 }과 { status: 1, ord_date: -1 }이 인덱스 교차가 이루어지고 정렬조건은 컴파운드 인덱스이므로 잘 동작한다.
인덱스 교차 및 컴파운드 인덱스
인덱스 교차로 인해 복합 인덱스를 생성할 필요가 없다 .
그러나 목록 순서(즉, 인덱스에 키가 나열되는 순서)와 정렬 순서(즉, 오름차순 또는 내림차순)가 모두 복합 인덱스 에서 중요하기 때문에 복합 인덱스는 다음을 포함하지 않는 쿼리 조건을 지원하지 않을 수 있다.
인덱스 접두사 키 또는 다른 정렬 순서를 지정한다.
예)
db.orders.createIndex({ status: 1, ord_date: -1 })
위와 같이 컴파운드 인덱스가 정의 되어 있을 때, 다음 쿼리는 인덱스의 효과를 누릴 수가 있다.
db.orders.find({ status: { $in: ["A", "P" ] }})
db.orders.find(
{
ord_date: { $gt: new Date("2014-02-01") },
status: { $in:[ "P", "A" ] }
}
)
하지만 아래의 쿼리는 선행 인덱스가 정의되어야 한다는 규칙에 위배되기 때문에 인덱스가 동작하지 않는다.
db.orders.find({ ord_date: { $gt: new Date("2014-02-01") }})
db.orders.find({}).sort({ ord_date: 1 })
그러나 만약 인덱스가 아래와 같이 정의되어 있다면, 인덱스 교차가 발동되어 위 4개의 모든 쿼리가 인덱스의 효과를 얻어 성능이 향샹된다.
{ status: 1 }
{ ord_date: -1 }
결론
컴파운드 인덱스와 인덱스 교차, 둘 중 무엇을 써야 할까?
각각의 방식에는 조건과 한계가 존재한다.
컴파운드 인덱스
1. 정렬을 할 때 선언하는 키의 순서와 각 키의 정렬 방향이 중요하다.
2. 정렬 순서는 인덱스 Prefix 규칙을 따라야 한다.
인덱스 교차
1. 컴파운드 인덱스와 같은 문제에서 자유롭다.
2. 쿼리의 검색 조건에 사용한 인덱스와 별개로 선언된 인덱스를 정렬 조건으로 사용 할 수 없다.
3. 대체로 컴파운드 인덱스에 비해 성능이 느리다.
'데이터베이스 > MongoDB' 카테고리의 다른 글
[MongoDB] 몽고DB Dump & Restore (Backup) (0) | 2023.04.04 |
---|---|
[MongoDB] 접두사 인덱스, 등치 (Index Prefix, Equality)란? (0) | 2023.03.20 |
[MongoDB] 인덱스 검색, 인덱스 정렬 방식에 따른 검색속도 차이 (0) | 2023.03.20 |
[MongoDB] Single Field Indexes, Compound Index (단일 인덱스, 복합 인덱스) (0) | 2023.03.14 |
[MongoDB] 인덱스(index)란? 인덱스 설계 시 고려할 점 (0) | 2023.03.13 |
댓글