본문 바로가기
데이터베이스/MongoDB

[MongoDB] 인덱스 교차 (Index Interserction)

by minhyeok.lee 2023. 3. 20.
반응형

[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. 대체로 컴파운드 인덱스에 비해 성능이 느리다.

 

 

반응형

댓글