쿼리 최적화
인덱스는 쿼리 작업에서 프로세스 하는 데이터 양을 줄여 읽기 작업의 효율성을 향상시킵니다. 이는 MongoDB 내에서 쿼리를 충족시키는 데 관련된 작업을 간소화합니다.
읽기 작업을 지원하는 인덱스 생성
애플리케이션 이 특정 필드 또는 필드 설정하다 에서 컬렉션 을 쿼리하는 경우 쿼리된 필드 의 인덱스 또는 필드 설정하다 의 복합 인덱스 로 인해 쿼리 가 전체 컬렉션 을 스캔하여 쿼리 결과를 찾고 반환하지 못할 수 있습니다. . 인덱스에 대한 자세한 내용은 MongoDB 의 인덱스에 대한 전체 문서를 참조하세요.
예시
애플리케이션이 type
필드에 있는 inventory
컬렉션을 쿼리합니다. type
필드의 값은 사용자 중심입니다.
var typeValue = <someUserInput>; db.inventory.find( { type: typeValue } );
이 쿼리의 성능을 개선하려면 type
필드의 inventory
컬렉션에 오름차순 또는 내림차순 인덱스를 추가합니다. [1] mongosh
에서는 db.collection.createIndex()
메서드를 사용하여 인덱스를 생성할 수 있습니다.
db.inventory.createIndex( { type: 1 } )
이 인덱스는 type
필드에 대한 쿼리가 전체 컬렉션을 스캔하여 결과를 반환하는 것을 방지할 수 있습니다.
인덱스를 사용하여 쿼리의 성능을 분석하려면 쿼리 성능 분석을 참조하십시오.
읽기 작업을 최적화하는 것 외에도 인덱스는 정렬 작업을 지원하고 보다 효율적인 스토리지 활용을 허용할 수 있습니다. 인덱스 생성에 대한 자세한 내용은 db.collection.createIndex()
및 인덱스를 참조하세요.
[1] | 단일 필드 인덱스의 경우 오름차순과 내림차순 간의 선택은 중요하지 않습니다. 하지만 복합 인덱스의 경우 선택이 중요합니다. 자세한 내용은 인덱싱 순서를 참조하세요. |
쿼리 선택성
쿼리 선택도는 쿼리 조건자(predicate)가 컬렉션에서 문서를 얼마나 잘 제외하거나 필터링하는지를 나타냅니다. 쿼리 선택도는 쿼리가 인덱스를 효과적으로 사용할 수 있는지 또는 인덱스를 전혀 사용할 수 있는지 여부를 결정할 수 있습니다.
선택적 쿼리가 많을수록 더 적은 비율의 문서가 일치합니다. 예를 들어 고유한 _id
필드의 동등성 매치는 최대 하나의 문서와 일치할 수 있으므로 매우 선별적입니다.
덜 선택적인 쿼리는 더 많은 비율의 문서와 일치합니다. 덜 선택적인 쿼리는 인덱스를 효과적으로 사용하지 못하거나 또는 전혀 사용할 수 없습니다.
예를 들어, 부등호 연산자 $nin
과 $ne
는 대부분의 인덱스와 일치하기 때문에 매우 선택적이지 않습니다. 결과적으로, 인덱스가 있는 $nin
또는 $ne
컬렉션의 모든 문서를 스캔해야 하는 $nin
또는 $ne
쿼리보다 빈번하게 성능이 떨어질 수 있습니다.
regular expressions
의 선택성은 표현식 자체에 따라 다릅니다. 자세한 내용은 표현식 및 인덱스 사용을 참조하세요.
커버되는 쿼리
커버드 쿼리(covered query)는 인덱스만을 사용하여 완전히 충족할 수 있는 쿼리로, 문서를 검사할 필요가 없습니다. 인덱스가 쿼리를 커버 할 때는 다음 조건이 모두 적용됩니다:
쿼리의 모든 필드(애플리케이션에서 지정한 필드와 샤딩 목적 등 내부적으로 필요한 필드 모두)는 인덱스의 일부입니다.
결과에서 반환되는 모든 필드가 동일한 인덱스에 있습니다.
쿼리에서
null
과 같은 필드가 없는 경우(예: 예를 들어 다음 쿼리 술어는 커버된 쿼리를 생성할 수 없습니다:{ "field": null }
{ "field": { $eq: null } }
예시
inventory
컬렉션에는 type
및 item
필드에 대한 다음 인덱스가 있습니다.
db.inventory.createIndex( { type: 1, item: 1 } )
이 인덱스는 type
및 item
필드를 쿼리하고 item
필드만 반환하는 다음 작업을 다룹니다.
db.inventory.find( { type: "food", item:/^c/ }, { item: 1, _id: 0 } )
지정한 인덱스가 쿼리를 포함하도록 하려면 인덱스에는 _id
필드가 포함되어 있지 않으므로 프로젝션 문서에서 명시적으로 _id: 0
를 지정하여 결과에서 _id
필드를 제외해야 합니다.
내장된 문서
인덱스는 내장된 문서 내의 필드에 대한 쿼리를 커버할 수 있습니다.
예를 들어 다음과 같은 형식의 문서가 있는 collection userdata
가 있다고 가정해 봅시다.
db.userdata.insertOne( { _id: 1, user: { login: "tester" } } )
컬렉션의 인덱스는 다음과 같습니다.
db.userdata.createIndex( { "user.login": 1 } )
{ "user.login": 1 }
인덱스는 다음 쿼리를 포함합니다.
db.userdata.find( { "user.login": "tester" }, { "user.login": 1, _id: 0 } )
참고
내장된 문서의 필드를 인덱싱하려면 점 표기법을 사용합니다. 포함된 Field에 인덱스 만들기를 참조하세요.
멀티키 커버링
인덱스가 인덱스를 멀티키로 만드는 필드를 추적하는 경우 멀티키 인덱스는 비배열 필드에 대한 쿼리를 처리할 수 있습니다.
멀티키 인덱스 는 배열 필드에 대한 커버 쿼리를 할 수 없습니다.
멀티키 인덱스가 포함된 적용 쿼리의 예는 멀티키 인덱스 페이지의 적용 쿼리를 참조하세요.
성능
인덱스에는 쿼리에 필요한 모든 필드가 포함되어 있기 때문에 MongoDB는 쿼리 조건을 충족하고 인덱스만을 사용하여 결과를 반환할 수도 있습니다.
인덱스만 쿼리하는 것이 인덱스 외부의 문서를 쿼리하는 것보다 훨씬 빠를 수 있습니다. 인덱스 키는 일반적으로 카탈로그에 포함된 문서보다 작으며, 인덱스는 일반적으로 RAM에서 사용 가능하거나 디스크에 순차적으로 배치됩니다.
제한 사항
인덱스 유형
모든 인덱스 유형이 query를 처리할 수 있는 것은 아닙니다. 커버드 인덱스 지원에 대한 자세한 내용은 해당 인덱스 유형의 설명서 페이지를 참조하십시오.
샤드 컬렉션에 대한 제한 사항
mongos
에서 실행할 때, 샤드 키가 포함된 인덱스가 있는 경우에만 인덱스는 샤드된 컬렉션에 대한 쿼리를 처리할 수 있습니다.
explain
쿼리가 적용 쿼리인지 확인하려면 db.collection.explain()
또는 explain()
메서드를 사용합니다. 해당 쿼리를 참조하세요.