Số 04. Dev gà - Hero Pagination
Hello! I'm Zu.Doan
Series này mình muốn tạo ra để note lại những kiến thức, đoạn code, issues, solutions mà mình gặp phải trong quá trình làm việc với Project thực tế.
1. Phân trang xịn xò trong MongoDB
Cách tiếp cận phổ thông là sử dụng skip và limit
db.collection.find({}).skip(50000).limit(1000)
Việc sử dụng skip bản chất MongoDB vẫn phải duyệt qua từng đó dữ liệu và sẽ cắt dữ liệu tại vị trí skip đó. Có nghĩa đối với ví dụ trên, MongoDB vẫn sẽ phải duyệt qua 51000 documents và cắt bỏ 50000 document đầu tiên.
Cách tiếp cận của Hero là sử dụng cursor
Đối với page = 1, ta vẫn sử dụng skip và limit như bình thường, bởi vì:
- Trang 1 sẽ có skip = 0, do đó vấn đề hiệu suất là tương đương với việc sử dụng cursor
- Cùng với đó chúng ta cũng cần một giá trị làm mốc để có thể sử dụng cursor
Đối với page > 1, ta sẽ xác định được giá trị _id của vị trí 1000, từ đó ta có thể thực thi truy vấn sau để lấy 1000 bản ghi tiếp theo
db.collection.find({ _id: { $gt: gia_tri_id_1000 } }).limit(1000)
Khi page càng tăng, việc sử dụng cách tiếp cận cũ sẽ tăng số lượng documents cần skip đi và tốc độ truy vấn sẽ giảm xuống.
Ở đây mình đã test với collection có 100k bản ghi, một lượng không nhiều tuy nhiên các bạn có thể nhìn thấy rõ sự khác biệt về tốc độ truy vấn, từ đó có thể liên tưởng tới collection có dữ liệu lớn hơn sẽ tạo sự khác biệt như thế nào.

Tham khảo:
