ฉันต้องการใช้อินสแตนซ์ 10 รุ่นสุดท้ายและมีรหัสนี้:
Model.objects.all().order_by('-id')[:10]
เป็นความจริงหรือไม่ที่รับอินสแตนซ์ทั้งหมดก่อนจากนั้นจึงใช้เพียง 10 ครั้งล่าสุดเท่านั้น มีวิธีใดที่มีประสิทธิภาพมากกว่านี้ไหม?
ฉันต้องการใช้อินสแตนซ์ 10 รุ่นสุดท้ายและมีรหัสนี้:
Model.objects.all().order_by('-id')[:10]
เป็นความจริงหรือไม่ที่รับอินสแตนซ์ทั้งหมดก่อนจากนั้นจึงใช้เพียง 10 ครั้งล่าสุดเท่านั้น มีวิธีใดที่มีประสิทธิภาพมากกว่านี้ไหม?
คำตอบ:
ชุดค้นหา Django ขี้เกียจ นั่นหมายความว่าแบบสอบถามจะเข้าสู่ฐานข้อมูลเฉพาะเมื่อคุณขอผลลัพธ์โดยเฉพาะ
ดังนั้นจนกว่าคุณจะพิมพ์หรือใช้ผลลัพธ์ของแบบสอบถามคุณสามารถกรองเพิ่มเติมโดยไม่มีการเข้าถึงฐานข้อมูล
ดังที่คุณเห็นด้านล่างรหัสของคุณเรียกใช้คิวรีหนึ่ง sql เพื่อดึงข้อมูลเฉพาะ 10 รายการสุดท้าย
In [19]: import logging
In [20]: l = logging.getLogger('django.db.backends')
In [21]: l.setLevel(logging.DEBUG)
In [22]: l.addHandler(logging.StreamHandler())
In [23]: User.objects.all().order_by('-id')[:10]
(0.000) SELECT "auth_user"."id", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email", "auth_user"."password", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."is_superuser", "auth_user"."last_login", "auth_user"."date_joined" FROM "auth_user" ORDER BY "auth_user"."id" DESC LIMIT 10; args=()
Out[23]: [<User: hamdi>]
ที่จริงฉันคิดว่าLIMIT 10
จะถูกส่งไปยังฐานข้อมูลดังนั้นการแบ่งส่วนจะไม่เกิดขึ้นใน Python แต่ในฐานข้อมูล
ดูการ จำกัด ชุดแบบสอบถามสำหรับข้อมูลเพิ่มเติม
ดูเหมือนว่าโซลูชันในคำถามจะไม่ทำงานกับ Django 1.7 อีกต่อไปและทำให้เกิดข้อผิดพลาด: "ไม่สามารถเรียงลำดับข้อความค้นหาใหม่ได้เมื่อมีการใช้งานชิ้น"
ตามเอกสารhttps://docs.djangoproject.com/en/dev/topics/db/queries/#limiting-querysetsบังคับให้พารามิเตอร์“ ขั้นตอน” ของ Pice Slice ของไวยากรณ์ประเมินแบบสอบถาม มันทำงานด้วยวิธีนี้:
Model.objects.all().order_by('-id')[:10:1]
ยังคงฉันสงสัยว่าขีด จำกัด จะดำเนินการใน SQL หรือ Python ชิ้นผลอาร์เรย์ทั้งหมดส่งกลับ ไม่มีประโยชน์ที่จะเรียกรายการขนาดใหญ่ไปยังหน่วยความจำแอปพลิเคชัน
ใช่. หากคุณต้องการดึงข้อมูลชุดย่อยของวัตถุที่ จำกัด คุณสามารถใช้รหัสด้านล่าง:
ตัวอย่าง:
obj=emp.objects.all()[0:10]
จุดเริ่มต้น 0 เป็นทางเลือกดังนั้น
obj=emp.objects.all()[:10]
โค้ดด้านบนส่งคืน 10 อินสแตนซ์แรก
ในฐานะที่เป็นส่วนเสริมและการสังเกตคำตอบที่มีประโยชน์อื่น ๆ มันก็คุ้มค่าที่จะสังเกตว่าการ [:10]
แบ่งส่วนข้อมูลจะส่งคืน10 องค์ประกอบแรกของรายการไม่ใช่ 10 รายการสุดท้าย
ในการรับ 10 คนสุดท้ายคุณควรทำ[-10:]
แทน (ดูที่นี่ ) สิ่งนี้จะช่วยคุณหลีกเลี่ยงการใช้order_by('-id')
กับ-
เพื่อย้อนกลับองค์ประกอบ
Product.objects.filter(~Q(price=0))[-5:]
ทำให้ฉันเกิดข้อผิดพลาดเดียวกัน: "ไม่รองรับการสร้างดัชนีเชิงลบ"