Lesson 13 / الدرس 13
Page 900 is slower than page 1 / الصفحة 900 أبطأ من الصفحة 1
OFFSET is the pagination everybody writes and it gets slower the further in you go, because the database has to produce and discard every row it skips. There is another way to ask the same question that does not.
OFFSET هو الترقيم الذي يكتبه الجميع ويبطؤ كلما توغّلت، لأن على قاعدة البيانات إنتاج كل صف تتخطاه ثم رميه. وثمة طريقة أخرى لطرح السؤال نفسه لا تفعل ذلك.
LIMIT 20 OFFSET 18000 does not jump to row 18,000. It produces eighteen thousand rows in order, throws all of them away, and returns the next twenty. Page one is instant, page nine hundred is a full scan with extra steps, and nothing about the query looks different.
LIMIT 20 OFFSET 18000 لا تقفز إلى الصف 18000. بل تنتج ثمانية عشر ألف صف بالترتيب، وترمي بها كلها، وتعيد العشرين التالية. فالصفحة الأولى فورية، والصفحة التسعمئة مسحٌ كامل بخطوات إضافية، ولا شيء في الاستعلام يبدو مختلفًا.The same three pages, asked two ways
-- Page 1 and page 2, the usual way. Watch the OFFSET grow.
SELECT id, name FROM guests ORDER BY id LIMIT 2;
SELECT id, name FROM guests ORDER BY id LIMIT 2 OFFSET 2;
SELECT id, name FROM guests ORDER BY id LIMIT 2 OFFSET 4;
-- The same three pages, asked the other way: carry the last id you saw
-- and ask for what comes after it. No OFFSET anywhere.
SELECT id, name FROM guests WHERE id > 0 ORDER BY id LIMIT 2;
SELECT id, name FROM guests WHERE id > 2 ORDER BY id LIMIT 2;
SELECT id, name FROM guests WHERE id > 4 ORDER BY id LIMIT 2;
What you give up
-
Jumping to an arbitrary page. Keyset gives you next and previous, not "page 47" — because it does not know where page 47 starts without counting. If your interface has numbered pages, this is the conversation to have. القفز إلى صفحة اعتباطية. فالمفتاح يعطيك التالي والسابق لا «صفحة 47» — لأنه لا يعرف أين تبدأ الصفحة 47 دون عدّ. وإن كان في واجهتك صفحات مرقّمة، فهذه هي المحادثة الواجبة.
-
A total page count, for the same reason and the reason the full-scan lesson gave: counting everything is itself a full scan. وعدد الصفحات الكلي، للسبب نفسه وللسبب الذي أعطاه درس المسح الكامل: فعدّ كل شيء مسحٌ كامل بذاته.
-
Sorting by anything you like. The column you page by has to be indexed and has to break ties — two rows with the same date need a second column, usually the id, or a row gets shown twice or skipped. والترتيب بما تشاء. فالعمود الذي ترقّم به يجب أن يكون مفهرسًا وأن يفضّ التعادل — فصفّان بالتاريخ نفسه يحتاجان عمودًا ثانيًا، المعرّف عادةً، وإلا عُرض صف مرتين أو تُخطّي.
Try it live / جرّب بنفسك
Check yourself / اختبر نفسك
1. What does LIMIT 20 OFFSET 18000 actually make the database do?
Which is why page one is instant and page nine hundred is a full scan with extra steps, while nothing about the query looks different.
2. Besides speed, what else is wrong with OFFSET on data that is changing?
Keyset pagination is immune to both, because it names where it left off rather than counting from the top on every page.
3. You page by check_in and two bookings share a date. What goes wrong?
The column you page by has to be indexed and has to be unique in effect. ORDER BY check_in, id makes the sequence total rather than nearly total.
Score / النتيجة: 0 / 3
Your task / مهمتك
Take a list in something you have built and page through it both ways. Write the OFFSET version and the keyset version of the same three pages, confirm they return identical rows, then say what your interface would have to give up to switch — and whether it can.
خذ قائمة في شيء بنيته ورقّمها بالطريقتين. اكتب نسخة OFFSET ونسخة المفتاح للصفحات الثلاث نفسها، وتأكد أنهما تعيدان الصفوف نفسها، ثم قل عمّ ستتخلى واجهتك للتحويل — وأتستطيع.
- The same three pages, written both ways, returning the same rows الصفحات الثلاث نفسها، مكتوبةً بالطريقتين، تعيد الصفوف نفسها
- The column you page by named, with the tie-breaker it needs العمود الذي ترقّم به مسمًّى، ومعه فاضّ التعادل الذي يحتاجه
- What the interface gives up, and whether that is acceptable here عمّ تتخلى الواجهة، وأمقبول ذلك هنا