쿼리 최적화는 쿼리 프로세스 해야 하는 데이터의 양을 줄입니다. 인덱스, 프로젝션, 쿼리 제한을 사용하여 성능을 개선하고 리소스 소비를 줄입니다. 컬렉션이 증가함에 따라 쿼리 성능을 주기적으로 검토하여 확장하다 시기를 결정합니다.
쿼리를 지원하는 인덱스 만들기
인덱스 는 필드 값을 별도의 데이터 구조에 저장 . 읽기 작업에서 MongoDB 전체 컬렉션 스캔하는 대신 인덱스 를 검색합니다. 쓰기 (write) 작업에서 MongoDB 컬렉션 과 인덱스 모두 업데이트합니다.
가장 일반적인 쿼리에 대한 인덱스를 생성합니다. 쿼리 여러 필드를 검색하는 경우 복합 인덱스만듭니다.
예시 들어 inventory 컬렉션 의 type 필드 에 대한 다음 쿼리 가정해 보겠습니다.
let typeValue = <someUserInput>; db.inventory.find( { type: typeValue } );
이 쿼리 의 성능을 향상시키려면 type 필드 에 인덱스 추가합니다.
db.inventory.createIndex( { type: 1 } )
[1] mongosh에서 db.collection.createIndex()를 사용합니다.
쿼리 성능을 분석 하려면 설명 설명 계획 결과 해석을 참조하세요.
| [1] | 단일 필드 인덱스의 경우 인덱스 의 순서는 중요하지 않습니다. 복합 인덱스의 경우 필드 순서는 인덱스 지원하는 쿼리에 영향을 줍니다. 자세한 내용은 복합 인덱스 정렬 순서를 참조하세요. |
선택적 쿼리 만들기
쿼리 선택도는 쿼리 문서를 얼마나 잘 필터링하는지 측정하고 쿼리가 인덱스를 효과적으로 사용할 수 있는지 여부를 결정합니다.
고도로 선택적인 쿼리 는 더 적은 수의 문서와 일치하며 인덱스를 더 효과적으로 사용합니다. 인스턴스 를 들어
_id에 대한 동등성 매치 최대 하나의 문서 와 일치할 수 있으므로 매우 선별적입니다.덜 선택적인 쿼리 는 더 많은 문서를 일치시키고 인덱스를 덜 효율적으로 사용합니다.
예를 들어, 부등호 연산자 $nin과 $ne는 대부분의 인덱스와 일치하기 때문에 매우 선택적이지 않습니다. 결과적으로, 인덱스가 있는 $nin 또는 $ne 컬렉션의 모든 문서를 스캔해야 하는 $nin 또는 $ne 쿼리보다 빈번하게 성능이 떨어질 수 있습니다.
regular expression 의 선택성은 표현식 자체에 따라 달라집니다. 자세한 내용은 정규 표현식 및 인덱스 사용을 참조하세요.
필요한 데이터만 프로젝트
문서에서 필드의 하위 집합이 필요한 경우 필요한 필드만 반환하여 성능을 개선할 수 있습니다. 프로젝션은 네트워크 트래픽과 처리 시간을 줄입니다.
예시 들어 timestamp, title, author 및 abstract 필드만 반환하는 다음 쿼리 가정해 보겠습니다.
db.posts.find( {}, { timestamp : 1, title : 1, author : 1, abstract : 1} ).sort( { timestamp : -1 } )
$project 집계 단계를 사용하는 경우, 이 단계는 일반적으로 파이프라인의 마지막 단계로, 클라이언트에 반환할 필드를 지정하는 데 사용됩니다.
파이프라인 의 시작 또는 중간에 $project 단계를 사용하여 후속 파이프라인 단계로 전달되는 필드 수를 줄이면 데이터베이스 이 최적화를 자동으로 수행하므로 성능이 향상되지 않을 수 있습니다.
자세한 내용은 쿼리에서 반환할 프로젝트 필드를 참조하세요.
예시
커버된 쿼리 얻으려면 프로젝션된 필드를 인덱스 . ESR(동등성, 정렬, 범위) 규칙 은 인덱스의 필드 순서에 적용됩니다.
예시 들어 inventory 컬렉션 에 대한 다음 인덱스 가정해 보겠습니다.
db.inventory.createIndex( { type: 1, _id: 1, price: 1, item: 1, expiryDate: 1} )
위의 쿼리 기술적으로 정확하지만 쿼리 성능을 최적화하도록 구조화되어 있지 않습니다.
다음 쿼리 보다 효율적인 복합 인덱스 위해 ESR 규칙을 적용합니다.
db.inventory.aggregate([ { $match: {type: "food", expiryDate: { $gt: ISODate("2025-07-10T00:00:00Z") }}}, { $sort: { item: 1 }}, { $project: { _id: 1, price: 1} } ])
인덱스 와 쿼리 ESR 규칙을 따릅니다.
type는 동등성 매치 (E)에 사용되므로 인덱스 의 첫 번째 필드 입니다.item정렬(S)에 사용되므로 인덱스 에서type뒤에 옵니다.expiryDate범위 쿼리 (R )에 사용되므로 인덱스 의 마지막 필드 입니다.
쿼리 결과 제한
MongoDB 커서 는 결과를 배치로 반환합니다. 필요한 결과의 수를 알고 있는 경우 해당 값을 limit() 메서드에 전달하여 네트워크 리소스 사용량을 줄입니다.
정렬 후 결과를 제한하여 반환되는 문서를 알 수 있습니다. 예시 들어, 다음 쿼리 posts 컬렉션 에서 10 의 가장 최근 결과만 반환합니다.
db.posts.find().sort( { timestamp : -1 } ).limit(10)
자세한 내용은 limit()를 참조하세요.
인덱스 힌트 사용
쿼리 옵티마이저 특정 작업에 가장 적합한 인덱스 선택합니다. 그러나 hint() 메서드를 사용하여 특정 인덱스 강제로 실행할 수 있습니다. 이는 성능 테스트 또는 필드 여러 인덱스에 나타나서 MongoDB 사용하는 인덱스 보장해야 하는 경우에 유용합니다.
서버 측 작업 사용
$inc 연산자 사용하여 문서의 값을 늘리거나 줄일 수 있습니다. 연산자 문서 선택하고 클라이언트 사이드에서 간단한 수정을 수행한 다음 서버 에 문서 쓰는 대신 서버 사이드에서 필드 값을 증가시킵니다. 또한 연산자 여러 애플리케이션 인스턴스가 동일한 필드 동시에 업데이트 때 경합 상태를 방지합니다.
해당 쿼리 실행
커버 쿼리 는 문서를 검사하지 않고도 인덱스 로 완전히 충족할 수 있는 쿼리 입니다. 인덱스 다음 사항이 모두 참일 때 쿼리 포함합니다.
쿼리 의 모든 필드( 애플리케이션 에서 지정한 필드와 샤딩 과 같이 내부적으로 필요한 모든 필드 포함)는 인덱스 의 일부입니다.
결과에서 반환되는 모든 필드가 동일한 인덱스에 있습니다.
쿼리에서
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 필드를 제외해야 합니다.
내장된 문서
인덱스는 내장된 문서 내의 필드에 대한 쿼리를 커버할 수 있습니다.
예시 를 들어 다음 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에 인덱스 만들기를 참조하세요.
멀티키 커버링
인덱스 가 멀티키로 만드는 필드를 추적하는 경우 멀티키 인덱스는 필드 아닌 필드에 대한 쿼리를 처리할 수 있습니다.
멀티키 인덱스는 배열 필드에 대한 쿼리를 처리할 수 없습니다.
예시는 멀티키 인덱스 페이지에서 해당 쿼리 를 참조하세요.
성능
포함된 쿼리는 쿼리 조건 과 일치하고 인덱스 만 사용하여 결과를 반환합니다. 인덱스 키는 일반적으로 문서보다 작고 인덱스는 일반적으로 RAM 에 있거나 디스크에 순차적으로 저장되기 때문에 문서를 가져오는 것보다 빠릅니다.
제한 사항
인덱스 유형
모든 인덱스 유형 이 커버된 쿼리를 지원 것은 아닙니다. 특정 인덱스 유형에 대한 설명서를 참조하세요.
샤드 컬렉션
mongos에서 실행할 때, 샤드 키가 포함된 인덱스가 있는 경우에만 인덱스는 샤드된 컬렉션에 대한 쿼리를 처리할 수 있습니다.
결과 설명
쿼리 적용되는지 확인하려면 db.collection.explain() 또는 explain()를 사용합니다. 해당 쿼리를 참조하세요.