ช่วงนี้ได้ทำงานที่ต้องรองรับข้อมูลเยอะๆ เลยเกิดข้อสงสัยว่า ระหว่างใช้ skip()
และ limit()
กับการ find all
(การดึงข้อมูลทั้งหมด) แบบไหน performance ในการใช้งานดีกว่ากัน
ถ้าจะตอบแบบเร็วๆ เลย ทุกคนน่าจะพอรู้ว่า ถ้าเทียบกันใน 2 วิธีนี้ skip()
และ limit()
จะทำงานได้ดีกว่าการที่เราดึงข้อมูลทั้งหมด
เพราะด้าน performance ของการ query ใน MongoDB ระหว่างการดึงข้อมูลทั้งหมด กับการทำ pagination แบบมี skip()
และ limit()
นั้น การทำ pagination จะมี performance ที่ดีกว่า เนื่องจาก:
- การใช้ทรัพยากร: การ query ข้อมูลทั้งหมดจะใช้หน่วยความจำและ CPU มากกว่า โดยเฉพาะเมื่อชุดข้อมูลมีขนาดใหญ่
- การส่งข้อมูลผ่านเครือข่าย: การส่งข้อมูลจำนวนมากจะทำให้เครือข่ายทำงานหนัก และใช้เวลาในการรับส่งข้อมูลนานขึ้น
- การตอบสนองต่อผู้ใช้: การแสดงผลข้อมูลจำนวนมากทำให้แอพพลิเคชันตอบสนองช้าลง
แต่ก็มีสิ่งที่ต้องระวังในการใช้งานเหมือนกัน นั่นคือ การใช้ .skip()
กับข้อมูลจำนวนมากอาจมี performance ไม่ดี เพราะ MongoDB ยังต้องอ่านและข้ามเอกสารจำนวนมาก
ดังหน้าหากเราต้องการ performance ที่ดี สำหรับชุดข้อมูลขนาดใหญ่มากๆ ควรใช้เทคนิค cursor-based pagination โดยใช้ field ที่มี index แทน
วิธีที่ 1: ใช้ skip()
และ limit()
วิธีนี้เป็นการใช้เมธอด skip(n)
เพื่อข้ามเอกสาร n
รายการ และ limit(n)
เพื่อจำกัดจำนวนเอกสารที่ส่งกลับมา
// หน้า 1
db.students.find().limit(5);
// หน้า 2
db.students.find().skip(5).limit(5);
// หน้า 3
db.students.find().skip(10).limit(5);
แม้ว่า วิธีนี้จะใช้งานง่าย แต่เมื่อจำนวนเอกสารเพิ่มขึ้น การใช้ skip()
จะทำให้ประสิทธิภาพลดลง
เนื่องจาก MongoDB ต้องข้ามเอกสารทีละรายการจนถึงตำแหน่งที่ต้องการ ซึ่งอาจทำให้การตอบสนองช้าลงในกรณีที่มีข้อมูลจำนวนมาก
วิธีที่ 2: ใช้ _id
และ limit()
วิธีนี้จะใช้ประโยชน์จากคุณสมบัติของ ObjectId
ซึ่งมีการเรียงลำดับตามเวลาโดยธรรมชาติ และ _id
มีการสร้าง index โดยอัตโนมัติ
// หน้า 1
db.students.find().limit(10);
// หน้า 2
last_id = ... // ดึง `_id` ของเอกสารสุดท้ายจากหน้า 1
db.students.find({ '_id': { '$gt': last_id } }).limit(10);
วิธีนี้มีประสิทธิภาพสูงกว่า เมื่อจัดการกับชุดข้อมูลขนาดใหญ่ เนื่องจากไม่ต้องข้ามเอกสารเหมือน skip()
และสามารถใช้ index เพื่อค้นหาเอกสารที่ต้องการได้อย่างรวดเร็ว
สรุป
skip()
+limit()
: เหมาะสำหรับชุดข้อมูลขนาดเล็ก หรือ เมื่อไม่ต้องการความเร็วสูงมาก แต่ประสิทธิภาพจะลดลงเมื่อจำนวนเอกสารเพิ่มขึ้น_id
+limit()
: เหมาะสำหรับชุดข้อมูลขนาดใหญ่ เนื่องจากมีประสิทธิภาพสูง และสามารถใช้ index เพื่อค้นหาเอกสารได้เร็ว