티스토리 뷰

개발/DB

[MongoDB] batchSize 에 대한 고찰

드림&T 2012. 7. 19. 22:01

MongoDB 를 설치하고 트위터 타임라인 정보를 읽어와 매일 같이 붓고 있다. rate limit 정책상 막 들이붓진 못해도 그래도 10만건 정도는 샘플데이터를 만든거 같다. Java Driver 를 이용하여 데이터를 조회해서 원하는 기준으로 그룹핑을 하는 어플리케이션을 만들었는데 DBCursor 클래스에 있는 batchSize에 대한 궁금증이 생겼다.

 

공식홈페이지로 들어가서 관련 설명페이지를 찾았다.

 

http://www.mongodb.org/display/DOCS/Queries+and+Cursors

 

아래와 같은 내용이 있다.

 

Execution of queries in batches 


The MongoDB server returns query results to the client in batches. You can modify this behavior in two ways: You can specify batchSize(), which tells the server how many documents to return in each batch, or limit(), which determines the total number of documents to return for this query. (See Advanced Queries for setting limit and batchSize.)

 

If limit and batchSize are not specified, the first batch contains 101 documents, or enough documents to exceed 1 MB, whichever comes first. Otherwise, the server returns enough documents to satisfy the lesser of the batchSize or the limit. If the query matches more than that quantity of results and you would like them all to be returned, you need to either specify a larger limit or batchSize, or iterate through the result set to retrieve all results. Iterating a cursor will return enough documents in each batch to satisfy batchSize or to exceed 4 MB, whichever comes first.

 

A special case is if you sort a set of documents without an index. In that case, since MongoDB must load all the documents in order to sort them in memory, so it returns them all in the first batch.

 

Regardless of limit and batchSize, no batch will contain more than enough documents to exceed 4 MB.

 

간단히 요약하면... MongoDB 쿼리의 결과는 batch 단위로 데이터를 가져온다.

이것을 제어할 수 있는 건 2가지 파라메터가 있는데, batchSize 를 지정하거나, limit 값을 지정하는 것이다.

batchSize : 한 batch 당 가져오는 document 갯수.

limit : 쿼리의 결과로 가져올 총 갯수.

 

 

위 2가지 값을 셋팅하냐 안하느냐에 따라 아래와 같이 MongoDB 는 batchSize 를 정한다.

 

1. limit 나 batchSize 를 지정하지 않는 경우 : 기본적으로 batch 한번당 101 개의 document 결과를 가져온다. 하지만 document 당 너무 많은 데이터가 있는 경우, batch 한번당 데이터가 1MB가 넘어가면 그만 담는다.

 

2. limit 나 batchSize 를 지정하는 경우 : 지정한 수만큼 document를 가져온다. 예를 들어 어떤 쿼리의 결과가 엄청 많고 그것을 한번의 batch로 많은 데이터를 가져오고 싶으면, limit 혹은 batchSize를 그 결과수보다 더 큰수로 셋팅하면 된다. 근데 큰수로 셋팅하더라도 4MB 이상의 데이터를 한번의 batch 로 가져올 수 없다.

 

예외가 있는데 그건 인덱스 없이 데이터를 sort 할 때 이다. 이런 경우 MongoDB 는 인덱스가 없기 때문에 메모리에서 그 많은 데이터들을 정렬하기 위해 모든 document 를 로드하며 첫번째 batch에 모든 데이터를 가져온다. (이런 경우 빼고는) limit와 batchSize 상관없이, 어떤 batch 라도 4 MB 를 초과해 담을 수 없다.

 

[예제]

> // for문을 돌려서 간단한 데이터로 200개 document 를 등록한다.
> for (var i = 0; i < 200; i++) { db.foo.insert({i: i}); }
> var cursor = db.foo.find()
> // batchSize나 limit 값 지정없이 find 했으므로 기본 batch 크기인 101 documents
> cursor.objsLeftInBatch()
101

> // 한번에 모든 document들을 가져오기 위해 큰 limit 값을 셋팅하면 batchSize는 모든 document 수가 된다.
> var cursor = db.foo.find().limit(1000)
> cursor.objsLeftInBatch()
200

> // batchSize 가 limit 크기보다 작으면 batchSize가 우선한다.
> var cursor = db.foo.find().batchSize(10).limit(1000)
> cursor.objsLeftInBatch()
10

> // limit 가 batchSize 보다 작으면 limit 가 우선한다.
> var cursor = db.foo.find().batchSize(10).limit(5)
> cursor.objsLeftInBatch()
5

> // 각각 1MB 데이터로 10개의 document 를 등록한다.
> var megabyte = '';
> for (var i = 0; i < 1024 * 1024; i++) { megabyte += 'a'; }
> for (var i = 0; i < 10; i++) { db.bar.insert({s:megabyte}); }

> // limit나 batchSize를 지정하지 않았으므로 첫번째 batch는 1MB 에서 멈춘다. 
> // 결국 1개씩 반복적으로 데이터를 가져오게됨
> var cursor = db.bar.find()
> cursor.objsLeftInBatch()
1

위 글은 맨 위에 링크 걸어논 사이트에 있는 예제들이다. 사실 말로 읽는 것보단 예제로 이해하는 게 훨 빠르다.

참고로 cursor 객체에 objsLeftInBatch라는 함수가 있으며 해당 커서가 한번의 batch에 가져올 document 갯수를 보여주는 것 같다.


반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함