쿼리 최적화
인덱스는 쿼리 작업에서 프로세스 하는 데이터 양을 줄여 읽기 작업의 효율성을 향상시킵니다. 이는 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
필드를 제외해야 합니다.
내장된 문서
인덱스는 내장된 문서 내의 필드에 대한 쿼리를 커버할 수 있습니다.
예를 예시 다음 형식의 문서가 포함된 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 } )
참고
내장된 문서의 필드를 인덱스 하려면 점 표기법 을 사용합니다. 포함된 필드에 인덱스 만들기를 참조하세요.
멀티키 커버링
인덱스가 인덱스를 멀티키로 만드는 필드를 추적하는 경우 멀티키 인덱스는 비배열 필드에 대한 쿼리를 처리할 수 있습니다.
멀티키 인덱스는 배열 필드에 대한 쿼리를 처리할 수 없습니다.
멀티키 인덱스 가 있는 커버 쿼리 의 예시 는 멀티키 인덱스 페이지의 커버 쿼리 를 참조하세요.
성능
인덱스에는 쿼리에 필요한 모든 필드가 포함되어 있기 때문에 MongoDB는 쿼리 조건을 충족하고 인덱스만을 사용하여 결과를 반환할 수도 있습니다.
인덱스만 쿼리하는 것이 인덱스 외부의 문서를 쿼리하는 것보다 훨씬 빠를 수 있습니다. 인덱스 키는 일반적으로 카탈로그에 포함된 문서보다 작으며, 인덱스는 일반적으로 RAM에서 사용 가능하거나 디스크에 순차적으로 배치됩니다.
제한 사항
인덱스 유형
모든 인덱스 유형 이 쿼리를 처리할 수 있는 것은 아닙니다. 커버된 인덱스 지원 에 대한 자세한 내용은 해당 인덱스 유형의 설명서 페이지를 참조하세요.
샤드 컬렉션에 대한 제한 사항
mongos
에서 실행할 때, 샤드 키가 포함된 인덱스가 있는 경우에만 인덱스는 샤드된 컬렉션에 대한 쿼리를 처리할 수 있습니다.
explain
쿼리 가 포함된 쿼리 인지 확인하려면 db.collection.explain()
또는 explain()
메서드를 사용합니다. 해당 쿼리를 참조하세요.