2017-04-13 2 views
0

색인 생성이있는 위치 수집이 있습니다 timestamp_1, timestamp_2 and user_id 필드. 쿼리를 실행할 때 (다음 로그에서 볼 수 있음) 쿼리가 ~ 3 분 (175670ms) 걸립니다. 나는 왜 그런 일이 일어나는지 알지 못한다 !! 다음 MongoDB-Log를 첨부했습니다.
아무도 나에게 다음 로그를 설명 할 수 있고 어떻게 그것을 최적화 할 수 있습니까 ??설명 MongoDB 로그 출력

2017-04-12T17 : 04 : 33.759 + 0000 I COMMAND [conn167] 쿼리 위치 쿼리 모음 : {ORDERBY : {timestamp_1 : 1}, $ 쿼리 : { $와 : [{timestamp_1 : {$의 LTE : 1492016294486.0}}, {timestamp_2 { $ GTE : 1491993563400.0}}, {USER_ID "jkfjlsjfflki-14asddsd"}]}} planSummary : IXSCAN {USER_ID 1} IXSCAN {USER_ID : 1} ntoreturn : 1000 ntoskip : 0 keysExamined : 27254 docsExamined : 27254 hasSortStage : 1 cursorExhausted : 1 keyUpdates : 0 writeConflicts : 0 numYields : 3350 nreturned : 67 reslen : 176574 locks : {글로벌 : { acquireCount : {r : 6702}}, 데이터베이스 : {acquireCount : {r : 3351}} 컬렉션 : {acquireCount : {R : 3351}}} 175670ms

하나 더 질문 : 나는 그래서 "_id"필드에 어떤 단점이 방법으로 내 자신의 가치를 창출하고있다 ?? 난 그냥 문자열 값을 생성하고 아무 문제없이 mongoDb 인덱스를 기대하고있다.

2017-04-12T17 : 04 : 41.979 + 0000 I [conn150] 쿼리 db.users 쿼리 COMMAND : {ORDERBY : {_id : 1}, $ 쿼리 : {_id : "USR-dfhsddf- 14905426shfkjdhf "}} planSummary : iDHACK ntoreturn 1 ntoskip : 0 keysExamined 1 docsExamined 1 idhack : 1 cursorExhausted 1 keyUpdates : 0 writeConflicts : 0 numYields : 0 nreturned 1 reslen : 1,291 자물쇠 {전역을 {acquireCount {R : 2}} 데이터베이스 : {acquireCount : {R : 1}} 컬렉션 : {acquireCount : {r은 1}}} 2627ms

미리 감사드립니다 !!

답변

0

두 번째 질문에 먼저 답하십시오. _id에 자신의 값을 사용하는 것이 좋습니다. MongoDB는이를 적절하게 색인화합니다. 이렇게하면 중복이 없도록하는 것이 응용 프로그램의 책임입니다.

기본 MonogDB ObjectId 유형에는 값에 타임 스탬프도 포함됩니다. 즉, ObjectId 일 때 _id 필드로 정렬하면 삽입 순서 (또는 ObjectId가 생성 된 주문의 기술적 타임 스탬프)로 결과가 반환됩니다.

로그 출력의 경우 쿼리 성능 출력 값은 데이터베이스 프로필러의 값입니다. 값 목록은 https://docs.mongodb.com/manual/reference/database-profiler/에서 확인할 수 있습니다.

쿼리 성능에 매우 유용한 도구는 explain(), https://docs.mongodb.com/manual/reference/method/cursor.explain/https://docs.mongodb.com/manual/reference/explain-results/입니다. 쿼리가 수행되는 방식을 자체 시스템에서 테스트해야합니다.

개별 필드의 컬렉션에 3 가지 다른 인덱스 (timestamp_1, timestamp_2user_id)가있는 것처럼 보입니다.

또한에 의해 주문하는 값을

  • timestamp_1
  • timestamp_2이 값
  • user_id보다 큰 값보다 작 일치 한 :

    쿼리는 세 개의 필드를 비교한다 출력의 timestamp_1 필드

    planSummary: IXSCAN { user_id: 1 }, IXSCAN { user_id: 1 } 쿼리 플래너는 다시하지 않은, 정렬에 사용할 user_id에 인덱스를 선택하는 쿼리에 대한 user_id에 인덱스를 선택하는 것을 주장하는 당신이 실제로에 정렬 할 필드. 참고로 https://groups.google.com/forum/#!topic/mongodb-user/nQlmVdODo-M을 참조하십시오.

    keysExamined:27254은 인덱스 스캔이 인덱스의 27254 키를 검사했다는 것을 의미합니다. docsExamined:27254은 MongoDB가 27245 개의 문서를 디스크에서 꺼내 내용을 검사한다는 의미입니다. nreturned:67은 쿼리 결과가 67 개의 문서를 반환했다고 명시합니다. user_id 색인이 스캔되고 27254 개의 일치 항목을 찾으면 각 문서가 모음에서 검색됩니다. 해당 문서가 구문 분석되고 timestamp* 필드가 비교되고 67 개의 일치하는 레코드가 반환됩니다. timestamp_1timestamp_2 색인은 사용되지 않습니다.

    MongoDB는 색인을 B-TREE로 저장하고 복합 색인 (https://docs.mongodb.com/manual/indexes/)을 허용합니다. 새로운 인덱스 조합을 테스트하고, 결과를 프로파일 링하고, 애플리케이션에 가장 적합한 인덱스를 확인할 수 있습니다. 3 개의 필드가 모두 포함 된 복합 색인을 사용하면 검색어 만 사용하여 모든 검색어 입력란 (user_id, timestamp_1timestamp_2)을 분석 할 수 있으므로 MongoDB에서 디스크를 읽을 때 필요한 문서 수를 줄일 수 있습니다. 하나의 잠재적 인 예는 다음과 같습니다

    db.collection.createIndex({user_id:1, timestamp_1:1, timestamp_2:-1) 
    

    이 인덱스는 몽고 쿼리 계획은 다음 timestamp_1이 값보다 작은 경우 다음 결과를 찾습니다 user_id 필드와 일치 timestamp_2이 값보다 큰 경우 더 이상의 결과를 찾을 수있다. timestamp_1timestamp_2 앞에 나와 있기 때문에 일치하는 레코드가 이미 정렬되어 MongoDB에서 정렬 단계를 건너 뛸 수 있습니다. 성능이 더 좋은지 확인하려면 자체 시스템에서이를 테스트해야합니다. 컬렉션에있는 문서의 카디널리티에 따라 user_id 필드보다 먼저 타임 스탬프 필드를 넣을 수 있습니다.