복합 인덱스
MongoDB는 단일 인덱스 구조에 collection 문서 내의 여러 필드 [1] 에 대한 참고가 포함되는 복합 인덱스 를 지원합니다. 다음 다이어그램은 두 필드에 대한 복합 인덱스의 예를 보여줍니다.
[1] | MongoDB는 모든 복합 인덱스 에 대해 32 필드의 제한을 적용합니다. |
복합 인덱스는 여러 필드에서 일치하는 쿼리를 지원할 수 있습니다.
호환성
MongoDB Atlas 에서 호스팅되는 배포에 복합 인덱스를 사용할 수 있습니다.
MongoDB Atlas에서 호스팅되는 배포의 인덱스 관리에 대해 자세히 알아보려면 인덱스 생성, 보기, 삭제 및 숨기기를 참조하세요.
복합 색인 만들기
복합 인덱스 를 만들려면 다음 프로토타입과 유사한 작업을 사용합니다.
db.collection.createIndex( { <field1>: <type>, <field2>: <type2>, ... } )
인덱싱된 필드의 순서는 주어진 쿼리에 대한 특정 인덱스의 효율성에 큰 영향을 미칩니다. 대부분의 복합 인덱스의 경우 ESR(동등성, 정렬, 범위) 규칙 을 따르면 효율적인 인덱스를 만드는 데 도움이 됩니다.
중요
다음 문서 와 유사한 문서가 들어 있는 products
컬렉션 을 가정해 보겠습니다.
{ "_id": ObjectId(...), "item": "Banana", "category": ["food", "produce", "grocery"], "location": "4th Street Store", "stock": 4, "type": "cases" }
다음 작업은 item
및 stock
필드에 오름차순 인덱스를 생성합니다.
db.products.createIndex( { "item": 1, "stock": 1 } )
복합 인덱스에 나열된 필드의 순서는 중요합니다. 인덱스에는 item
필드 값을 기준으로 먼저 정렬된 문서에 대한 참조가 포함되며, item
필드의 각 값 내에서는 주식 필드 값을 기준으로 정렬된 문서에 대한 참조가 포함됩니다. 자세한 내용은 정렬 순서 를 참조하세요.
모든 인덱스 필드에서 일치하는 쿼리를 지원하는 것 외에도, 복합 인덱스는 인덱스 필드의 접두사와 일치하는 쿼리를 지원할 수 있습니다. 즉, 인덱스는 item
필드와 item
및 stock
필드 모두에 대한 쿼리를 지원합니다.
db.products.find( { item: "Banana" } ) db.products.find( { item: "Banana", stock: { $gt: 5 } } )
자세한 내용은 접두사를 참조하세요.
정렬 순서
인덱스는 오름차순(1
) 또는 내림차순(-1
) 정렬 순서로 필드에 대한 참조를 저장 합니다. 단일 필드 인덱스의 경우 MongoDB 는 어느 방향으로든 인덱스 를 탐색할 수 있으므로 키의 정렬 순서는 중요하지 않습니다. 그러나 복합 인덱스 의 경우 인덱스 가 정렬 작업을 지원 수 있는지 여부를 결정할 때 정렬 순서가 중요할 수 있습니다.
username
및 date
필드가 있는 문서가 포함된 컬렉션 events
을 생각해 보겠습니다. 애플리케이션은 username
값을 먼저 오름차순으로 정렬한 다음 date
값을 내림차순으로(즉, 최근에서 마지막으로) 정렬하여 결과를 반환하는 쿼리를 실행할 수 있습니다.
db.events.find().sort( { username: 1, date: -1 } )
또는 username
값을 내림차순으로 정렬한 다음 date
값을 오름차순으로 정렬하여 결과를 반환하는 쿼리입니다.
db.events.find().sort( { username: -1, date: 1 } )
다음 인덱스는 이러한 정렬 작업을 모두 지원할 수 있습니다.
db.events.createIndex( { "username" : 1, "date" : -1 } )
그러나 위의 인덱스는 다음과 같이 username
값을 오름차순으로 정렬한 다음 date
값을 오름차순으로 정렬하는 것을 지원할 수 없습니다 .
db.events.find().sort( { username: 1, date: 1 } )
정렬 순서 및 복합 인덱스에 대한 자세한 내용은 인덱스를 사용하여 쿼리 결과 정렬을 참조하세요.
접두사
인덱스 접두사는 인덱싱된 필드의 시작 부분 집합입니다. 예를 들어 다음과 같은 복합 인덱스를 가정해 보겠습니다.
{ "item": 1, "location": 1, "stock": 1 }
인덱스에는 다음과 같은 인덱스 접두사가 있습니다.
{ item: 1 }
{ item: 1, location: 1 }
복합 인덱스의 경우, MongoDB는 인덱스를 사용하여 인덱스 접두사에 대한 쿼리를 지원할 수 있습니다. 따라서 MongoDB는 다음 필드에 대한 쿼리에 인덱스를 사용할 수 있습니다.
item
필드item
필드 및location
필드,item
필드 및location
필드 및stock
필드.
MongoDB는 item
필드가 접두사에 해당하므로 인덱스를 사용하여 item
및 stock
필드에 대한 쿼리를 지원할 수도 있습니다. 그러나 이 경우 인덱스는 인덱스가 item
및 stock
에만 있는 경우만큼 효율적으로 쿼리를 지원하지 않습니다.
item
및 stock
에 대한 쿼리에서 location
인덱스 접두사를 생략하므로 location
뒤에 오는 stock
인덱스 필드를 사용할 수 없습니다. 인덱스의 item
필드만 이 쿼리를 지원할 수 있습니다. 자세한 내용은 쿼리를 지원하는 인덱스 생성 을 참조하세요. 인덱스:
item
의 키와 일치합니다.stock
필드의IXSCAN
단계 내에서 필터를 수행합니다.필터링된 결과를 반환합니다.
예를 들어 "item":
"saccharomyces cerevisiae"
및 "stock": 60
에 대한 쿼리를 생각해 보겠습니다. collection에 "item":
"saccharomyces cerevisiae"
와 일치하는 문서 10,000개가 포함되어 있고 해당 문서 중 "stock": 60
와 일치하는 문서가 100개 있는 경우 쿼리는 10,000개의 키를 검사합니다. IXSCAN
단계에서 쿼리는 stock
필드를 기준으로 이러한 키를 필터링하고 다음 단계에 100개의 결과만 반환합니다.
item
필드가 없으면 나열된 필드 중 어느 것도 접두사 인덱스에 해당하지 않기 때문에 MongoDB는 인덱스를 사용하여 다음 필드를 포함하는 쿼리를 지원할 수 없습니다.
location
필드stock
필드 또는location
및stock
필드
접두사에 복합 인덱스와 인덱스가 모두 있는 컬렉션이 있는 경우(예: { a: 1, b: 1 }
및 { a: 1 }
), 두 인덱스 모두 희소 또는 고유 제약 조건이 없는 경우 접두사에서 인덱스를 제거할 수 있습니다(예: { a: 1 }
). MongoDB는 접두사 인덱스를 사용했을 모든 상황에서 복합 인덱스를 사용합니다.
인덱스 교차
버전 2.6부터 MongoDB는 인덱스 교차 를 사용하여 쿼리를 처리할 수 있습니다. 쿼리를 지원하는 복합 인덱스를 생성할지, 아니면 인덱스 교차에 의존할지 여부는 시스템의 특성에 따라 달라집니다. 자세한 내용은 인덱스 교차 및 복합 인덱스 에서 확인 가능합니다.
희소 복합 인덱스
복합 인덱스에는 다양한 유형의 희소 인덱스가 포함될 수 있습니다. 인덱스 유형의 조합이 복합 인덱스가 문서를 어떻게 매칭하는지 결정합니다.
이 표에는 다양한 유형의 희소 인덱스가 포함된 복합 인덱스의 동작이 요약되어 있습니다.
복합 인덱스 구성 요소 | 컴파운드 인덱스 동작 |
---|---|
Ascending indexes Descending indexes | 적어도 하나의 키에 대한 값을 포함하는 문서만 인덱싱합니다. |
문서에 geospatial 필드 중 하나에 대한 값이 포함된 경우에만 문서를 인덱싱합니다. 오름차순 또는 내림차순 인덱스의 문서는 인덱싱하지 않습니다. | |
text 필드 중 하나와 일치하는 경우에만 문서의 인덱스를 생성합니다. 오름차순 또는 내림차순 인덱스의 문서를 인덱싱하지 않습니다. |
추가 고려 사항
인덱스를 빌드하는 동안 애플리케이션의 성능이 저하되거나 인덱싱되는 collection에 대한 읽기/쓰기 액세스가 제한될 수 있습니다.
인덱스 빌드 프로세스에 대한 자세한 내용은 채워진 collection 에 대한 인덱스 빌드, 특히 복제된 환경에서 의 인덱스 빌드 섹션을 참조하세요.
일부 드라이버는 1
NumberLong(1)
을(를) 사용하여 인덱스 순서를 지정합니다. 결과 인덱스는 동일합니다.