2017-10-02 1 views
0

많은 문서 (> 100M)를 쿼리해야하며 문서 5000 개 (각각 4-5MB)를 요청하고 있습니다. 어떤 이유로 인해 나머지가 상당한 시간 (~ 8-9.5 초)을 걸리는 동안 첫 번째 요청 (_id 필터링없이)은 빠르게 (~ 1.5 초) 반환됩니다.MongoDB 처음 읽은 후 느리게 읽음

이제 500 개의 문서 (각각 ~ 500kB)를 일괄 적으로 읽으면 타이밍이 상당히 좋아지며 (0.5-0.8 초) 모든 요청에 ​​일관됩니다.

나는 skip + limit 메서드가 훨씬 성능이 떨어지는 것을 보았으므로 _id + limit 페이지 매김 방법을 사용하고 있습니다.

다음은 내 프로세스 샘플입니다.

var mongodb = require("mongodb") 
var bytes = require("bytes") 

... 

var filter = { 
    '_id': { '$gt': this._lastId } 
} 

if(mongodb.ObjectId.isValid(this._lastId)) { 
    filter['_id'] = { '$gt': this._lastId } 
} 

var cursor = this.conn.collection(collectionName) 
    .find(filter) 
    .limit(5000) 

var start = new Date().getTime() 
cursor.toArray(function(err, docs) { 
    if (err) { ... } 

    var elapsed = (new Date().getTime() - start)/1000 

    console.log(
     "Docs:", docs.length, 
     "Size:", bytes(sizeof(docs)), 
     "Took:", elapsed + " seconds" 
    ) 

    var lastDoc = docs[docs.length - 1] 

    this._lastId = lastDoc._id 
}) 

... 
+0

일괄 처리 크기가 250에서 500 사이이면 최상의 결과를 얻을 수 있습니다. 5000의 배치가 너무 많아서 MongoDB 드라이버가 내부적으로 최대 1000의 크기로 나눕니다. – Saleem

답변

0

나는, 문제는 흥미로운 발견을 재현하기 위해 노력하고 같은 결과에 온 : 5000 ID 0에서 첫 번째 전화가 빠르고 모든 다른 사람들이 일관되게 이상 (약 7 배)

이입니다 필터없이 읽는 것과 관련이 있습니다. 몽고 쉘에서 명령을 실행하고 설명을하면 0에서 5000 사이의 값을 읽을 때 필터가 적용되지 않습니다.

.batchSize()을 사용하면 한 번에 더 많은 문서를 얻을 수 있습니다 귀하의 인물, 각 문서는 약 1KB입니다). 기본값은 커서 반복 당 20입니다. .toArray() 함수를 실행하면 5000 워드 프로세서가 전송 될 때까지 MongoDB에서 응용 프로그램으로 20KB의 청크를 전송합니다. 더 큰 일괄 처리를 사용하는 것이 더 최적화 될 수 있습니다. 다른 값을 시도해야하지만 작은 덩어리의 네트워크 오버 헤드를 줄이면 한 번에 500KB를 얻는 것으로 시작합니다. cursor.forEach()은 (batchSize (n) 청크 단위로) 처리 될 때 데이터를 전송할 때 더 잘 작동한다는 것을 알 수 있습니다. 이 경우 모든 문서를 검사하기를 원할 경우 전체 모음이나 5,000 청크를 쿼리하는 것이 중요하지 않습니다.

커서는 데이터베이스 연결이나 커서를 닫을 때까지 연결을 열어두고 MongoDB 서버에 리소스를 할당하지만 커서는 크기가 커지지 않고 배치 데이터 만 보유합니다.

한 가지 더 중요한 것은 작은 배치를 사용하는 것이 더 빠르지 않다는 것입니다. 한 문서 당 시간이 비슷하고 10 배 적은 문서가 약 10 배 빠릅니다.

+0

더 작은 배치에 대해서도 같은 것을 알았지 만, 작은 배치는 시스템의 메모리로 더 잘 작동 할 수 있습니다. 'cursor.batchSize()'의 사용법을 자세히 설명 할 수 있습니까? 나는 그것에 익숙하지 않다. 그것은 소진 될 때까지 열린 연결을 유지합니까? 전체 문서 보관 시간이 오래 걸릴 수있는 100M + 문서의 경우 –

+0

답을 수정합니다. –

관련 문제