Pagination Nedir?
Pagination, büyük veri setlerini küçük parçalara bölerek hem performansı hem de kullanıcı deneyimini iyileştirmeyi amaçlayan bir tekniktir.
Örneğin bir blog sisteminde 100.000 kayıt olduğunu düşünelim. Bu verileri tek seferde çekmek:
- DB yükünü artırır
- Response süresini uzatır
- Gereksiz RAM ve CPU tüketimine yol açar
Pagination sayesinde verileri parça parça sunarız → daha az veri, daha hızlı yüklenme.
Pagination Türleri
İki temel pagination yaklaşımı vardır:
- Offset Based Pagination
- Cursor Based Pagination
En yaygın kullanılan yöntem offset based olduğu için önce onu inceleyelim.
Offset Based Pagination
SQL’de LIMIT ve OFFSET kullanarak sayfalandırma yaparız.
Mantık basittir:
OFFSET→ Kaç kayıt atlanacakLIMIT→ Kaç kayıt getirilecek
Örneğin:
SELECT *
FROM posts
ORDER BY id
LIMIT 20 OFFSET 40;
Bu sorgu:
- İlk 40 kaydı atlar
- Sonraki 20 kaydı getirir
Page Mantığı
Eğer:
page = 3pageSize = 20
İse:
page 1 → 1–20
page 2 → 21–40
page 3 → 41–60
Formül:
Örnek:
- page = 3
- pageSize = 10
(3 - 1) * 10 = 20
Yani ilk 20 kaydı atla, 21’den itibaren getir.
Node.js tarafında:
const offset = (page - 1) * limit;
Offset Based’in Zayıf Noktası: Data Drift
Offset pagination’ın en büyük problemi **data drift (veri kayması)**dır.
Örnek:
Başlangıçta veriler:
1, 2, 3, 4, 5, 6, 7, 8, 9, 10
- limit = 3
- offset = 0
İlk sayfa → 1, 2, 3
Bu sırada 3, 4, 5 silindiğini düşünelim.
Yeni veri:
1, 2, 6, 7, 8, 9, 10
- sayfaya geçelim:
- limit = 3
- offset = 3
İlk 3 kayıt (1, 2, 6) atlanır.
Sonuç:
7, 8, 9
Burada 6 numaralı kayıt hiç gösterilmez → veri kayması oluşur.
Offset Based’in Performans Problemi
Offset arttıkça performans düşer.
Sebep:
Veritabanı her seferinde baştan başlayarak satırları saymak zorundadır.
Zaman karmaşıklığı:
Yani offset büyüdükçe CPU maliyeti lineer olarak artar.
Örnek execution plan çıktılarında:
- OFFSET 0 → daha düşük actual time
- OFFSET 10.000 → daha yüksek actual time
- OFFSET 100.000 → daha da yüksek actual time
DB, atlanacak satırları yine okumak zorundadır.
Index eklemek biraz iyileştirme sağlar fakat problemi tamamen çözmez.
Cursor Based Pagination
Bu problemi cursor based pagination ile çözeriz.
Mantık:
“En son gördüğüm kayıttan sonraki verileri getir.”
Örnek:
SELECT *
FROM posts
WHERE created_at < '2024-01-01'
ORDER BY created_at DESC
LIMIT 10;
Burada:
- Satır atlanmaz
- DB index üzerinden direkt hedef noktaya gider
Zaman karmaşıklığı:
Yani veri 100 bin de olsa 100 milyon da olsa performans büyük ölçüde sabit kalır.
Execution plan’da:
- Table scan yerine
- Index range scan kullanılır
Bu da ciddi performans avantajı sağlar.
Offset vs Cursor Karşılaştırması
| Kriter | Offset Based Pagination | Cursor Based Pagination |
|---|---|---|
| CPU Kullanımı | Offset arttıkça artar (O(n)) | Düşük ve stabil (O(log n)) |
| Hafıza (RAM) | Büyük offsetlerde daha fazla RAM tüketir | Minimum RAM kullanır |
| I/O (Disk) | Gereksiz satırları okur | Sadece gerekli satırları okur |
| Data Drift | Var | Yok |
| Ölçeklenebilirlik | Zayıf | Yüksek |
| Sayfa Atlama | Kolay (Direkt page numarası ile) | Zor (Cursor gerektirir) |
- Küçük datasetlerde offset pagination yeterlidir.
- Büyük ve sürekli değişen datasetlerde cursor based pagination tercih edilmelidir.
- Özellikle yüksek trafikli production sistemlerde cursor yaklaşımı çok daha ölçeklenebilir ve tutarlıdır.