3 백만 개의 문서와 다음 색인이있는 컬렉션이 하나 있습니다.
{ts : 1}, {u_id : 1}
이들은 복합 색인이 아니라 두 개의 개별 오름차순 색인입니다.
이 쿼리를 실행할 때 :
db.collection.find ({u_id : 'user'}). sort ({ts : -1}). skip (0) .limit (1)
+ 100ms가 걸립니다. 다음 로그가 있습니다.
2017-04-15T06 : 42 : 01.147 + 0000 I COMMAND [conn783] query
db.collection query : {orderby : {ts : -1}, $ query : {
u_id : "user-ki-id}} planSummary : IXSCAN { u_id :
1}, IXSCAN {u_id : 1} ntoreturn : 1 ntoskip : 0 keysExamined : 10795
docsExamined : 10795 hasSortStage : 1 cursorExhausted : 1 keyUpdates : 0
writeConflicts : 0 numYields : 86 nreturned : 1 reslen : 771 locks : {Global : {
acquireCount : {r : 174}}, 데이터베이스 : {acquireCount : {r : 87}},
컬렉션 : {acquireCount : {r : 87}}} 246ms
문제에 대한 몇 가지 주목할 점 :
그래서 내 질문은 다음과 같습니다.
이 컬렉션에서 범위 검색을 실행할 때도 똑같은 일이 발생합니다. 이 작업에는 3-5 초가 걸립니다.
편집 : {u_id : 1, ts : -1} 인덱스 만 추가했습니다. 다른 모든 인덱스를 제거합니다 (_id 제외). 여전히 처음 쿼리 실행에는 + 100ms가 걸립니다. 이것은 일어나지 않아야합니다.
질문:
db.getCollection ( 'locations') .find ({u_id : "USR-WOWU"}) .sort ({ts : -1}) .explain (true)
산출::
/ * 1 * / { "queryPlanner": { "plannerVersion": 1, "namespace": "db_name.collection_name", "indexFilterSet": false, "parsedQuery": { "user_id": { "$ eq": "USR -WOWU "}},"winningPlan ": {"stage ":"FETCH ","inputStage ": {"stage ":"IXSCAN ","keyPattern ": {"u_id ": 1.0,"ts ": -1.0} , "indexName": "u_id_1_ts_-1", "isMultiKey": false, "isUnique": false, "isSparse": false, "isPartial": false, "indexVersion": 1, "direction": "forward", " indexBounds ": {"u_id ": ["[\ "USR-WOWU \", \ "USR-WOWU \"] "],"ts ":[ "[MaxKey, MinKey]"]}}}, "rejectedPlans": []}, "executionStats": { "executionSuccess": true, "nReturned": 164, "executionTimeMillis": 119, "totalKeysExamined": 164, "totalDocsExamined": 164, "executionStages": { "stage": "FETCH", "nReturned": 164, "executionTimeMillisEstimate": 120,"executionTimeMillisEstimate": 120,"executionTimeMillisEstimate": 120,"works": 165, "advanced": 164, "needTime": 0, "needYield": 0, "saveState": 3, "restoreState": 3, "isEOF": 1, "invalidates": 0, "docsExamined ": 164,"alreadyHasObj ": 0,"inputStage ": {"stage ":"IXSCAN ","nReturned ": 164,"executionTimeMillisEstimate ": 0,"작동 ": 165,"advanced ": 164,"needTime " : 0, "needYield": 0, "saveState": 3, "restoreState": 3, "isEOF": 1, "무효화": 0, "keyPattern": { "u_id": 1.0, "ts": -1.0 }, "indexName": "u_id_1_ts_-1", "isMultiKey": false, "isUnique": false, "isSparse": false, "isPartial ": false,"indexVersion ": 1,"direction ":"forward ","indexBounds ": {"u_id ": ["[\ "USR-WOWU \", \ "USR-WOWU \"] "], "ts": [ "[MaxKey, MinKey]"]}, "keysExamined": 164, "dupsTested": 0, "dupsDropped": 0, "seenInvalidated": 0}}, "allPlansExecution": []}, " serverInfo ": {"host ":"manish ","port ": 22022,"version ":"3.2.13 ","gitVersion ":"23899209cad60aaafe114f6aea6cb83025ff51bc "},"ok ": 1.0}USR-WOWU \ "]"], "ts": [ "[MaxKey, MinKey]"]}, "keysExamined": 164, "dupsTested": 0, "dupsDropped": 0, "seenInvalidated": 0}}, "allPlansExecution": []}, "serverInfo": { "host": "manish", "port": 22022, "version": "3.2.13", "gitVersion": "23899209cad60aaafe114f6aea6cb83025ff51bc"}, "ok": 1.0}USR-WOWU \ "]"], "ts": [ "[MaxKey, MinKey]"]}, "keysExamined": 164, "dupsTested": 0, "dupsDropped": 0, "seenInvalidated": 0}}, "allPlansExecution": []}, "serverInfo": { "host": "manish", "port": 22022, "version": "3.2.13", "gitVersion": "23899209cad60aaafe114f6aea6cb83025ff51bc"}, "ok": 1.0}gitVersion ":"23899209cad60aaafe114f6aea6cb83025ff51bc "},"ok ": 1.0}gitVersion ":"23899209cad60aaafe114f6aea6cb83025ff51bc "},"ok ": 1.0}
위의 jSON을 복사하고 편집기로 형식을 지정하십시오.
위의 쿼리 후 다음 동일한 쿼리가 ~ 2ms 내에 응답합니다. 그러나 삽입을 거의하지 않으면 1 분 후에 같은 것이 반복됩니다. (첫 번째 쿼리는 + 100ms 시간이 걸리고 그 다음에는 ~ 2ms가 걸립니다.)
내 mongoDB에서 구성하는 데 무언가 누락되었거나 필요한 것이 있습니까?
왜 일어나고 있는가
이 로그 줄 의 docsExamined:10795
및 hasSortStage:1
부분은 쿼리가 디스크에서 10,795를 검색 한 다음 결과를 메모리에 정렬하고 있음을 나타냅니다. 로그 행 해석에 대한 가이드는 여기 에서 찾을 수 있습니다 .
메모리 내 정렬을 방지하기 위해이 쿼리를 인덱싱하면 성능이 향상 될 수 있습니다 .
이 쿼리의 경우 색인 생성을 시도해야합니다 { 'u_id' : 1, 'ts' : -1 }
.
{ts : -1}과 같은 인덱싱을 내림차순으로 변경하면 정말 가치가 있습니까?
인덱스는 어느 방향 으로든 읽을 수 있으므로 인덱스 순서는 단일 필드 인덱스에서 그다지 중요하지 않습니다. 그러나 정렬 순서는 복합 인덱스 에서 매우 중요 할 수 있습니다 .
계획 설명을 기반으로 쿼리는 이제 인덱스를 올바르게 사용하여 인덱스에서 결과를 순서대로 읽어 메모리 내 정렬을 방지합니다. 이것은 쿼리에서 ~ 100ms를 떨어 뜨린 것처럼 보입니다.
그러나이 쿼리는 더 이상 .skip(0).limit(1)
. 이를 다시 추가하고 성능이 향상되는지 확인할 수 있습니까?
배포에 문제가없는 것 같습니다. 이 동작은 완전히 인덱싱되지 않은 쿼리의 경우 정상으로 보입니다.
기존 결과 ( " 작업 집합 ")가 이미 메모리에 저장되어 있으므로 정확히 동일한 쿼리를 재실행하는 것이 빠릅니다 . 새 데이터를 삽입하면 쿼리 결과가 변경 될 수 있으므로 결과를 다시 메모리로 읽어야 할 수 있습니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다