희소 인덱스
이 페이지의 내용
희소 인덱스에는 인덱스 필드에 null 값이 포함되어 있더라도 인덱스된 필드가 있는 문서에 대한 항목만 포함됩니다. 인덱스는 인덱스된 필드가 누락된 모든 문서를 건너뜁니다. 인덱스는 컬렉션의 모든 문서를 포함하지 않으므로 " sparse " 입니다. 반대로 희소가 아닌 인덱스는 컬렉션의 모든 문서를 포함하며 인덱싱된 필드를 포함하지 않는 문서에 대해서는 null 값을 저장합니다.
중요
MongoDB는 부분 인덱스를 생성하는 옵션을 제공합니다. 부분 인덱스는 희소 인덱스 기능의 상위 집합을 제공합니다. 부분 인덱스는 희소 인덱스보다 선호되어야 합니다.
희소 인덱스 만들기
희소 인덱스를 만들려면 sparse
옵션을 true
로 설정한 상태에서 db.collection.createIndex()
메서드를 사용하십시오.
예를 들어 mongosh
에서 다음 연산은 addresses
컬렉션의 xmpp_id
필드에 희소 인덱스를 생성합니다.
db.addresses.createIndex( { "xmpp_id": 1 }, { sparse: true } )
인덱스는 xmpp_id
필드를 포함하지 않는 문서의 인덱스를 생성하지 않습니다.
참고
MongoDB의 희소 인덱스를 다른 데이터베이스의 블록 수준 인덱스와 혼동하지 마세요. 해당 인덱스는 특정 필터가 있는 밀집 인덱스라고 생각하면 됩니다.
행동
희소 인덱스 및 불완전한 결과
희소 인덱스로 인해 쿼리 및 정렬 작업에 대한 불완전한 결과 집합이 생성되는 경우, hint()
가 인덱스를 명시적으로 지정하지 않는 한 MongoDB는 해당 인덱스를 사용하지 않습니다.
예를 들어 { x: { $exists: false } }
쿼리는 명시적으로 힌트를 주지 않는 한 x
필드의 희소 인덱스를 사용하지 않습니다. 동작에 대한 자세한 예시는 컬렉션의 희소 인덱스가 전체 결과를 반환할 수 없음을 참조하세요.
컬렉션의 모든 문서에 대해 count()
(을)를 수행할 때 희소 인덱스를 지정하는 hint()
(을)를 포함하면 (즉, 빈 쿼리 술어 사용), 희소 인덱스로 인해 잘못된 카운트가 발생하더라도 희소 인덱스가 사용됩니다.
db.collection.insertOne( { _id: 1, y: 1 } ); db.collection.createIndex( { x: 1 }, { sparse: true } ); db.collection.find().hint( { x: 1 } ).count();
정확한 개수를 얻으려면 컬렉션의 모든 문서 개수를 계산할 때 희소 인덱스와 함께 hint()
를 사용하지 마세요.
db.collection.find().count(); db.collection.createIndex( { y: 1 } ); db.collection.find().hint( { y: 1 } ).count();
기본적으로 희소로 설정되는 인덱스
다음 인덱스 유형은 항상 희소 설정을 갖습니다.
희소 복합 인덱스
복합 인덱스에는 다양한 유형의 희소 인덱스가 포함될 수 있습니다. 인덱스 유형의 조합이 복합 인덱스가 문서를 어떻게 매칭하는지 결정합니다.
이 표에는 다양한 유형의 희소 인덱스가 포함된 복합 인덱스의 동작이 요약되어 있습니다.
복합 인덱스 구성 요소 | 컴파운드 인덱스 동작 |
---|---|
Ascending indexes Descending indexes | 적어도 하나의 키에 대한 값을 포함하는 문서만 인덱싱합니다. |
문서에 geospatial 필드 중 하나에 대한 값이 포함된 경우에만 문서를 인덱싱합니다. 오름차순 또는 내림차순 인덱스의 문서는 인덱싱하지 않습니다. | |
text 필드 중 하나와 일치하는 경우에만 문서의 인덱스를 생성합니다. 오름차순 또는 내림차순 인덱스의 문서를 인덱싱하지 않습니다. |
Sparse 하고 고유한 속성
희소성과 고유성을 모두 갖춘 인덱스는 컬렉션에서 중복된 필드 값을 가진 문서가 있는 것을 방지하지만 키를 생략한 여러 문서를 허용합니다.
예시
컬렉션에 희소 인덱스 만들기
다음 문서가 포함된 컬렉션 scores
을 생각해 보겠습니다.
{ "_id" : ObjectId("523b6e32fb408eea0eec2647"), "userid" : "newbie" } { "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 } { "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 }
컬렉션에 score
필드에 희소 인덱스가 있습니다.
db.scores.createIndex( { score: 1 } , { sparse: true } )
그런 다음 scores
컬렉션에 대한 다음 쿼리는 희소 인덱스를 사용하여 score
필드가 90
미만 ($lt
)인 문서를 반환합니다.
db.scores.find( { score: { $lt: 90 } } )
userid "newbie"
문서에 score
필드가 포함되어 있지 않아 쿼리 기준을 충족하지 않기 때문에 쿼리는 희소 인덱스를 사용하여 결과를 반환할 수 있습니다.
{ "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }
컬렉션의 희소 인덱스가 완전한 결과를 반환할 수 없음
다음 문서가 포함된 컬렉션 scores
을 생각해 보겠습니다.
{ "_id" : ObjectId("523b6e32fb408eea0eec2647"), "userid" : "newbie" } { "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 } { "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 }
컬렉션에 score
필드에 희소 인덱스가 있습니다.
db.scores.createIndex( { score: 1 } , { sparse: true } )
userid "newbie"
문서는 score
필드를 포함하고 있지 않으므로 희소 인덱스는 해당 문서에 대한 항목을 포함하고 있지 않습니다.
scores
컬렉션의 모든 문서를 score
필드로 정렬하여 반환하는 다음 쿼리를 고려해 보세요.
db.scores.find().sort( { score: -1 } )
정렬이 인덱싱된 필드를 기준으로 이루어지더라도, MongoDB는 완전한 결과를 반환하기 위해 쿼리를 수행하기 위해 희소 인덱스를 선택하지 않습니다.
{ "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 } { "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 } { "_id" : ObjectId("523b6e32fb408eea0eec2647"), "userid" : "newbie" }
희소 인덱스를 사용하려면 hint()
로 인덱스를 명시적으로 지정합니다.
db.scores.find().sort( { score: -1 } ).hint( { score: 1 } )
인덱스을 사용하면 score
필드가 있는 문서만 반환됩니다.
{ "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 } { "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }
고유 제약 조건이 있는 희소 인덱스
다음 문서가 포함된 컬렉션 scores
을 생각해 보겠습니다.
{ "_id" : ObjectId("523b6e32fb408eea0eec2647"), "userid" : "newbie" } { "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 } { "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 }
다음 작업을 사용하여 score
필드에 고유 제약 조건 및 희소 필터를 사용하여 인덱스를 만들 수 있습니다.
db.scores.createIndex( { score: 1 } , { sparse: true, unique: true } )
이 인덱스는 score
필드에 대해 고유한 값을 가진 문서의 삽입을 허용하거나 score
필드를 포함하지 않는 문서를 허옹합니다. 따라서 scores
컬렉션의 기존 문서가 주어졌을 때 인덱스는 다음과 같은 삽입 작업을 허용합니다.
db.scores.insertMany( [ { "userid": "newbie", "score": 43 }, { "userid": "abby", "score": 34 }, { "userid": "nina" } ] )
그러나 score
값이 82
및 90
인 문서가 이미 존재하므로 인덱스는 다음 문서 추가를 허용하지 않습니다.
db.scores.insertMany( [ { "userid": "newbie", "score": 82 }, { "userid": "abby", "score": 90 } ] )
희소 및 비희소 고유 인덱스
MongoDB 5.0부터는 동일한 키 패턴을 가진 고유한 희소 인덱스와 고유한 비희소 인덱스가 단일 컬렉션에 존재할 수 있습니다.
고유하고 희소성 있는 인덱스 생성
이 예시에서는 동일한 키 패턴과 다른 sparse
옵션을 사용하여 여러 인덱스를 만듭니다.
db.scoreHistory.createIndex( { score : 1 }, { name: "unique_index", unique: true } ) db.scoreHistory.createIndex( { score : 1 }, { name: "unique_sparse_index", unique: true, sparse: true } )
기본 및 희소 인덱스 생성
sparse 옵션을 사용하거나 사용하지 않고 동일한 키 패턴으로 기본 인덱스를 생성할 수도 있습니다.
db.scoreHistory.createIndex( { score : 1 }, { name: "sparse_index", sparse: true } ) db.scoreHistory.createIndex( { score : 1 }, { name: "basic_index" } )