ช่วงนี้ได้ทำงานที่ต้องรองรับข้อมูลเยอะๆ เลยเกิดข้อสงสัยว่า ระหว่างใช้ skip() และ limit() กับการ find all (การดึงข้อมูลทั้งหมด) แบบไหน performance ในการใช้งานดีกว่ากัน

ถ้าจะตอบแบบเร็วๆ เลย ทุกคนน่าจะพอรู้ว่า ถ้าเทียบกันใน 2 วิธีนี้ skip() และ limit() จะทำงานได้ดีกว่าการที่เราดึงข้อมูลทั้งหมด

เพราะด้าน performance ของการ query ใน MongoDB ระหว่างการดึงข้อมูลทั้งหมด กับการทำ pagination แบบมี skip() และ limit() นั้น การทำ pagination จะมี performance ที่ดีกว่า เนื่องจาก:

  1. การใช้ทรัพยากร: การ query ข้อมูลทั้งหมดจะใช้หน่วยความจำและ CPU มากกว่า โดยเฉพาะเมื่อชุดข้อมูลมีขนาดใหญ่
  2. การส่งข้อมูลผ่านเครือข่าย: การส่งข้อมูลจำนวนมากจะทำให้เครือข่ายทำงานหนัก และใช้เวลาในการรับส่งข้อมูลนานขึ้น
  3. การตอบสนองต่อผู้ใช้: การแสดงผลข้อมูลจำนวนมากทำให้แอพพลิเคชันตอบสนองช้าลง

แต่ก็มีสิ่งที่ต้องระวังในการใช้งานเหมือนกัน นั่นคือ การใช้ .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 เพื่อค้นหาเอกสารได้เร็ว