ขั้นตอนการเรียงลำดับมากเกินไปการใช้ข้อมูลบัฟเฟอร์เกินขีด จำกัด ภายใน


85

การใช้รหัส:

all_reviews = db_handle.find().sort('reviewDate', pymongo.ASCENDING)
print all_reviews.count()

print all_reviews[0]
print all_reviews[2000000]

นับพิมพ์และการพิมพ์2043484all_reviews[0]

อย่างไรก็ตามเมื่อพิมพ์all_reviews[2000000]ฉันได้รับข้อผิดพลาด:

pymongo.errors.OperationFailure: ข้อผิดพลาดฐานข้อมูล: ข้อผิดพลาดของนักวิ่ง: การจัดเรียงลำดับขั้นตอนที่มากเกินไปการใช้ข้อมูลบัฟเฟอร์ของ 33554495 ไบต์เกินขีด จำกัด ภายในที่ 33554432 ไบต์

ฉันจะจัดการสิ่งนี้ได้อย่างไร?

คำตอบ:


119

คุณพบขีด จำกัด 32MB ในการจัดเรียงในหน่วยความจำ:

https://docs.mongodb.com/manual/reference/limits/#Sort-Operations

เพิ่มดัชนีในฟิลด์การเรียงลำดับ ซึ่งช่วยให้ MongoDB สามารถสตรีมเอกสารถึงคุณตามลำดับที่จัดเรียงแทนที่จะพยายามโหลดทั้งหมดลงในหน่วยความจำบนเซิร์ฟเวอร์และจัดเรียงในหน่วยความจำก่อนที่จะส่งไปยังไคลเอนต์


7
ดีกว่าที่จะประกาศดัชนีดังนั้นคุณไม่จำเป็นต้องเรียงลำดับใน RAM: เร็วขึ้นและเชื่อถือได้มากขึ้นการใช้งาน RAM ที่ จำกัด แทนที่จะเป็นแบบไม่ จำกัด หากคุณยืนยันให้เปลี่ยน "find" ของคุณเป็นการรวม (ซึ่งสามารถใช้ RAM 100MB ในการจัดเรียง) และตั้งค่า allowDiskUse: true เพื่อบอกให้เฟรมเวิร์กการรวมหกไปยังดิสก์หากมี RAM เกิน 100MB คาดว่าจะได้รับโทษจากประสิทธิภาพที่รุนแรงเมื่อเทียบกับการประกาศดัชนีที่เหมาะสม docs.mongodb.org/manual/reference/operator/aggregation/sort/…
A. Jesse Jiryu Davis

32
จริงๆแล้วมันสามารถเปลี่ยนแปลงได้ คุณต้องรันคำสั่งนี้: db.adminCommand({setParameter: 1, internalQueryExecMaxBlockingSortBytes: <limit in bytes>}). ที่มา: askubuntu.com/questions/501937/…
kumarharsh

6
สิ่งที่ควรทราบสำหรับผู้ใช้พังพอนว่าการตั้งค่าดัชนี: จริงบนเสาในสคีมาของคุณจะแก้ไขปัญหานี้ได้ ... พังพอนจะตรวจสอบสคีมาทั้งหมดของคุณและตรวจสอบให้แน่ใจว่าฟิลด์นั้นเป็นดัชนีจริงก่อนที่จะเริ่มแอป ... คุณปิดพฤติกรรมนี้ด้วย mySchema.set ('autoIndex', false);
Benjamin Conant

2
ฉันได้สร้างดัชนีในเขตข้อมูลการเรียงลำดับแล้ว แต่ก็ยังให้ข้อผิดพลาด "การดำเนินการจัดเรียงที่ใช้มากกว่าหน่วยความจำสูงสุด 33554432 ไบต์" อาจเป็นเพราะฉันใช้การจับคู่ก่อนการเรียงลำดับและตาม mongo doc หากคุณใช้การจับคู่ก่อนจัดเรียง การดำเนินการจะละเลยดัชนีและดำเนินการในการจัดเรียงหน่วยความจำเหนือระเบียนที่ตรงกันทั้งหมด
Amol Suryawanshi

11
หากนี่เป็นคำตอบที่ยอมรับก็ควรมีข้อมูลเกี่ยวกับวิธีการเพิ่มดัชนี
Philipp Ludwig

46

ตามที่กล่าวไว้kumar_harshในส่วนความคิดเห็นฉันต้องการเพิ่มประเด็นอื่น

คุณสามารถดูการใช้งานบัฟเฟอร์ปัจจุบันโดยใช้คำสั่งด้านล่างบนadminฐานข้อมูล:

> use admin
switched to db admin
> db.runCommand( { getParameter : 1, "internalQueryExecMaxBlockingSortBytes" : 1 } )
{ "internalQueryExecMaxBlockingSortBytes" : 33554432, "ok" : 1 }

มีค่าเริ่มต้น32 MB (33554432 ไบต์)ในกรณีนี้คุณกำลังใช้งานข้อมูลบัฟเฟอร์ไม่ดังนั้นคุณจึงสามารถเพิ่มขีด จำกัด บัฟเฟอร์ด้วยค่าที่เหมาะสมที่คุณกำหนดเองเช่น 50 MB ดังต่อไปนี้:

>  db.adminCommand({setParameter: 1, internalQueryExecMaxBlockingSortBytes:50151432})
{ "was" : 33554432, "ok" : 1 }

นอกจากนี้เรายังสามารถตั้งค่าขีด จำกัด นี้อย่างถาวรโดยใช้พารามิเตอร์ด้านล่างในไฟล์ config mongodb:

setParameter=internalQueryExecMaxBlockingSortBytes=309715200

หวังว่านี่จะช่วยได้ !!!

Note: คำสั่งนี้รองรับหลังจากเวอร์ชัน 3.0 ขึ้นไปเท่านั้น


วิธีตั้งค่าขีด จำกัด นี้ถาวรในไฟล์ config คืออะไร? ฉันมีเครื่องหน่วยความจำ 1 TB สำหรับ mongo และฉันต้องการที่จะหมุนมันอย่างถาวร
Samantha Atkins

@SamanthaAtkins ฉันได้อัปเดตคำตอบเพื่อตั้งค่านี้อย่างถาวรในไฟล์กำหนดค่า
JERRY

@JERRY ที่จะตั้งถาวรในราง ราง 5 / mongoid.yml?
ประทีปกุล

เจอแล้ว. รันที่เทอร์มินัลของฉันกับ: mongod และทำตามคู่มือzocada.com/setting-mongodb-users-beginners-guide
ประทีปกุล

24

แก้ไขด้วยการสร้างดัชนี

db_handle.ensure_index([("reviewDate", pymongo.ASCENDING)])

อย่าใช้ดัชนีที่เบาบางเนื่องจากจะถูกละเว้นหากคุณจัดเรียงในทุกเอกสาร
Charly Koza

15

หากคุณต้องการหลีกเลี่ยงการสร้างดัชนี (เช่นคุณแค่ต้องการตรวจสอบอย่างรวดเร็วและสกปรกเพื่อสำรวจข้อมูล) คุณสามารถใช้การรวมกับการใช้ดิสก์:

all_reviews = db_handle.aggregate([{$sort: {'reviewDate': 1}}], {allowDiskUse: true})

(ไม่แน่ใจว่าจะทำอย่างไรใน pymongo)


ใน pymongo db_handle.aggregate(pipe, allowDiskUse=True)จะเป็น ดูคำถามนี้สำหรับข้อมูลเพิ่มเติม!
Genarito


2

ในกรณีของฉันจำเป็นต้องแก้ไขดัชนี nessary ในรหัสและสร้างขึ้นใหม่:

rake db:mongoid:create_indexes RAILS_ENV=production

เนื่องจากหน่วยความจำล้นไม่เกิดขึ้นเมื่อมีดัชนีฟิลด์ที่จำเป็น

ป.ล.ก่อนหน้านี้ฉันต้องปิดการใช้งานข้อผิดพลาดเมื่อสร้างดัชนีแบบยาว:

# mongo
MongoDB shell version: 2.6.12
connecting to: test
> db.getSiblingDB('admin').runCommand( { setParameter: 1, failIndexKeyTooLong: false } )

อาจจำเป็นreIndex:

# mongo
MongoDB shell version: 2.6.12
connecting to: test
> use your_db
switched to db your_db
> db.getCollectionNames().forEach( function(collection){ db[collection].reIndex() } )
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.