2011-08-30 2 views
3

나는 3 개 숫자 속성을 포함하는 복합 _id가 KEYB 위해 50 만 개 동일한 값의 200 만 개 동일한 KeyA 값과 클러스터를 가지고MongoDB에서 Compound _id의 예상되는 동작은 무엇입니까?</p> <p>_id ": { "KeyA ": 0, "KEYB ": 0, "KeyC ": 0 } 문제</p> <p>데이터베이스

나의 이해는 내가 효율적으로 명령을 사용하여 KeyA 및 KEYB를 조회 할 수 있다는 것입니다.

find({ "_id.KeyA" : 1, "_id.KeyB": 3 }).limit(100) 
,691,363을) 제한없이

"cursor" : "BasicCursor", 
"nscanned" : 1000100, 
"nscannedObjects" : 1000100, 
"n" : 100, 
"millis" : 1592, 
"nYields" : 0, 
"nChunkSkips" : 0, 
"isMultiKey" : false, 
"indexOnly" : false, 
"indexBounds" : {} 

(결과는 다음과 같습니다 :이 쿼리를 설명 할 때210

결과입니다

"cursor" : "BasicCursor", 
"nscanned" : 2000000, 
"nscannedObjects" : 2000000, 
"n" : 500000, 
"millis" : 3181, 
"nYields" : 0, 
"nChunkSkips" : 0, 
"isMultiKey" : false, 
"indexOnly" : false, 
"indexBounds" : {} 

내가 알고있는 것처럼 BasicCursor 인덱스가 무시되었다는 것을 의미하고 두 쿼리가 있습니다 높은 실행 시간 - 심지어 100 개의 레코드를 요청한 경우에도 1.5 초 정도 걸립니다. 페이지 매김을 구현하기 위해 한계를 사용하려는 것이지만 너무 느립니다.

명령 :

find({ "_id.KeyA" : 1, "_id.KeyB": 3, , "_id.KeyC": 1000 }) 

올바르게 BtreeCursor를 사용하여 신속 화합물 _id가 올바른지 제안 행한다.

MongoDb의 1.8.3 버전을 사용하고 있습니다. 누군가가 예상되는 동작을 보았는지 또는 복합 인덱스를 사용/쿼리하는 방법을 잘못 이해했는지 확인할 수 있습니까?

감사합니다. 폴.

답변

10

인덱스는 화합물 인덱스가 아닙니다,하지만 전체 값의 인덱스 _id 필드. MongoDB는 인덱싱 된 필드를 조사하지 않고 대신 필드의 원시 BSON 표현을 사용하여 비교합니다 (올바르게 읽으면).

{_id.KeyA: 1, _id.KeyB: 1, _id.KeyC: 1} 이상의 실제 복합 색인이 필요합니다 (고유 색인이어야 함). _id에 색인을 지정할 수 없기 때문에 ObjectId으로 남겨 두는 것이 좋습니다 (색인이 작아지고 공간이 적어 짐) KeyA, KeyBKeyC 필드를 문서의 속성으로 유지하는 것이 좋습니다. 예 : {_id: ObjectId("xyz..."), KeyA: 1, KeyB: 2, KeyB: 3}

+0

Theo - 답장하는 동안 감사합니다. 본질적으로 mstreams와 같습니다. 귀하가 명시 적으로 _id 필드가 복합 색인을 제공하지 않는다는 점을 명시 적으로 지적 했으므로 답변을 수락했습니다 (파악하지 못한 비트) . 순진하게 가정하면, 자동으로 색인 된 _id 필드에 복합 키를 만든 경우 최종 결과는 복합 색인이됩니다. 당신은 살고 배웁니다. – Paul

8

원하는 동작에 대해 별도의 복합 색인이 필요합니다. 일반적으로 키 순서가 비교에서 중요하기 때문에 {a : 1, b : 1}은 {b : 1, a : 1}과 같지 않으므로 개체를 _id로 사용하지 않는 것이 좋습니다. 모든 드라이버가 객체에 키 순서를 유지 이후로는 다음과 같이 수행하여 스스로 발을 쏠 매우 쉽습니다 :

db.foo.save(db.foo.findOne())