2016-06-07 3 views
3

mongodb 콜렉션에서 임의의 문서를 선택할 수있는 방법은 여러 가지가 있습니다 (in this answer 참조). Mongodb 버전이 3.2 이상이면 집계 프레임 워크에서 $sample을 사용하는 것이 좋습니다. 그러나 많은 작은 문서가 포함 된 모음집에서는 매우 느립니다.

import timeit 
from random import randint 

import mongoengine as mdb 

mdb.connect("test-agg") 


class ACollection(mdb.Document): 
    name = mdb.StringField(unique=True) 

    meta = {'indexes': ['name']} 


ACollection.drop_collection() 

ACollection.objects.insert([ACollection(name="Document {}".format(n)) for n in range(50000)]) 


def agg(): 
    doc = list(ACollection.objects.aggregate({"$sample": {'size': 1}}))[0] 
    print(doc['name']) 

def skip_random(): 
    n = ACollection.objects.count() 
    doc = ACollection.objects.skip(randint(1, n)).limit(1)[0] 
    print(doc['name']) 


if __name__ == '__main__': 
    print("agg took {:2.2f}s".format(timeit.timeit(agg, number=1))) 
    print("skip_random took {:2.2f}s".format(timeit.timeit(skip_random, number=1))) 

결과는 다음과 같습니다 :

다음 코드는 문제를 시뮬레이션하고 "건너 랜덤"방법과 비교하는 mongoengine를 사용하여 내가 함께 성능 문제를 했어 어디

Document 44551 
agg took 21.89s 
Document 25800 
skip_random took 0.01s 

mongodb 과거에 내 대답은 항상 놀랍 기 때문에 집계 프레임 워크를 사용했습니다. $sample은 매우 느립니다.

여기에 뭔가가 있습니까? 이 예제에서 집계에 너무 오랜 시간이 걸리는 이유는 무엇입니까?

+1

실행중인 MongoDB 버전은 무엇입니까? 나는'$ sample'이 3.2.5에서 매우 느리다는 것을 발견했지만, 3.2.7에서 기본적으로 순간적으로 나타났습니다. – JohnnyHK

+0

아, 3.2.0 - 그때가 될 것입니다. 예, [this] (https://jira.mongodb.org/browse/SERVER-21887?jql=text%20~%20%22%24sample%22)는 알려진 버그임을 보여줍니다. –

+0

그래,하지만 3.2.5에서 수정 된 것으로 표시된대로 1M docs의 새로운 콜렉션과 함께 나에게 아직도 느린 이유는 모르겠다. – JohnnyHK

답변

2

이것은 WiredTiger 엔진 mongodb < 3.2.3에서 known bug의 결과입니다. to the latest version을 업그레이드하면이 문제가 해결됩니다.