2016-09-23 15 views
6

Tôi đang sử dụng pymongo để thực hiện cập nhật hàng loạt.
Danh sách tên dưới đây là một danh sách riêng biệt của tên (mỗi tên có thể có mutiple tài liệu trong bộ sưu tập)Cập nhật hàng loạt quá chậm

Mã 1:

bulk = db.collection.initialize_unordered_bulk_op() 
for name in names: 
    bulk.find({"A":{"$exists":False},'Name':name}).update({"$set":{'B':b,'C':c,'D':d}}) 
print bulk.execute() 

Mã 2:

bulk = db.collection.initialize_unordered_bulk_op() 
counter = 0 
for name in names: 
    bulk.find({"A":{"$exists":False},'Name':name}).update({"$set":{'B':b,'C':c,'D':d}}) 
    counter =counter + 1 
    if (counter % 100 == 0): 
     print bulk.execute() 
     bulk = db.collection.initialize_unordered_bulk_op() 
if (counter % 100 != 0): 
    print bulk.execute() 

Tôi có 50000 tài liệu trong bộ sưu tập của mình. Nếu tôi loại bỏ bộ đếm và câu lệnh (Mã 1), mã sẽ bị kẹt! Với câu lệnh if (Mã 2), tôi giả sử rằng thao tác này sẽ không mất nhiều hơn một vài phút nhưng nó đang sử dụng nhiều hơn thế! Bạn có thể vui lòng giúp tôi làm cho nó nhanh hơn hoặc tôi sai trong giả định của tôi ?!

Trả lời

6

Bạn rất có thể đã quên thêm chỉ mục để hỗ trợ truy vấn của mình! Thao tác này sẽ kích hoạt quét toàn bộ bộ sưu tập cho từng hoạt động của bạn, điều này thật chậm chạp (như bạn đã nhận ra).

Mã sau đây kiểm tra bằng cách sử dụng update_many và công cụ hàng loạt không có và có chỉ mục trên trường 'tên' và 'A'. Những con số bạn tự nói ra.

Lưu ý, tôi không đủ đam mê để làm điều này cho 50000 mà không có chỉ mục nhưng cho 10000 tài liệu. Kết quả cho 10000 là:

  • mà không cần chỉ mục và update_many: 38,6 giây
  • mà không cần chỉ mục và cập nhật hàng loạt: 28,7 giây
  • với chỉ mục và update_many: 3,9 giây
  • với chỉ số và cập nhật hàng loạt: 0,52 giây

Đối với 50000 tài liệu có chỉ mục được thêm, phải mất 2,67 giây. Tôi đã chạy thử nghiệm trên một cửa sổ máy và mongo chạy trên cùng một máy chủ trong docker.

Để biết thêm thông tin về chỉ mục, hãy xem https://docs.mongodb.com/manual/indexes/#indexes. Tóm lại: Các chỉ mục được giữ trong RAM và cho phép truy vấn nhanh và tra cứu tài liệu. Các chỉ mục phải chọn cụ thể để đối sánh các truy vấn của bạn.

from pymongo import MongoClient 
import random 
from timeit import timeit 


col = MongoClient()['test']['test'] 

col.drop() # erase all documents in collection 'test' 
docs = [] 

# initialize 10000 documents use a random number between 0 and 1 converted 
# to a string as name. For the documents with a name > 0.5 add the key A 
for i in range(0, 10000): 
    number = random.random() 
    if number > 0.5: 
     doc = {'name': str(number), 
     'A': True} 
    else: 
     doc = {'name': str(number)} 
    docs.append(doc) 

col.insert_many(docs) # insert all documents into the collection 
names = col.distinct('name') # get all distinct values for the key name from the collection 


def update_with_update_many(): 
    for name in names: 
     col.update_many({'A': {'$exists': False}, 'Name': name}, 
         {'$set': {'B': 1, 'C': 2, 'D': 3}}) 

def update_with_bulk(): 
    bulk = col.initialize_unordered_bulk_op() 
    for name in names: 
     bulk.find({'A': {'$exists': False}, 'Name': name}).\ 
      update({'$set': {'B': 1, 'C': 2, 'D': 3}}) 
    bulk.execute() 

print(timeit(update_with_update_many, number=1)) 
print(timeit(update_with_bulk, number=1)) 
col.create_index('A') # this adds an index on key A 
col.create_index('Name') # this adds an index on key Name 
print(timeit(update_with_update_many, number=1)) 
print(timeit(update_with_bulk, number=1)) 
+0

Cảm ơn sự giúp đỡ nhưng tôi nghĩ rằng thời gian bạn đã đưa ra ở trên không chính xác vì chúng không phải là 10000 tài liệu nhưng chỉ một nửa trong số đó (xem xét 0,5 và <= 0,5 đều bằng nhau có thể xảy ra). Ngoài ra, nó sẽ giúp ích nếu bạn có thể chia sẻ cách bạn lập chỉ mục các trường A và Tên cho người mới bắt đầu. Cảm ơn một lần nữa! – amazingCodingExperience

+0

Ngoài ra, làm thế nào để lập chỉ mục sẽ buộc chặt quá trình? Bạn có thể chia sẻ lý thuyết đằng sau điều đó không? – amazingCodingExperience

+0

Đã thêm thông tin vào câu trả lời của tôi. Tuy nhiên, mongodb cung cấp các khóa học trực tuyến khá tốt miễn phí: https://university.mongodb.com/courses/M101P/about Tôi đề nghị bạn nên thực hiện một trong số này để tăng tốc với mongo. – squanto773

Các vấn đề liên quan