
İmleç Tabanlı Sayfalama: Milyonuncu Sayfada Neden Yavaşlar?
Listeleme sayfanız ilk sayfalarda anında açılıyor. Ama kullanıcı ileri gittikçe yavaşlıyor ve beş yüzüncü sayfada zaman aşımına uğruyor. Sorgu aynı, veri aynı — ama maliyet katlanarak artıyor.
Bu yazı, büyük listelerde sayfalama yaklaşımlarını ele alıyor.
Klasik Sayfalamanın Sorunu
Atlama tabanlı sayfalama şöyle çalışır:
- Kayıtlar sıralanır.
- Belirli sayıda kayıt atlanır.
- Sonraki kayıtlar döndürülür.
İkinci adım maliyeti üretir ve sezgiye aykırıdır: veritabanı atlanacak kayıtları hızlıca geçmez — onları da okur, sıralar ve sonra atar; yüz bininci kayıttan başlayan bir sayfa için yüz bin kaydı işlemek zorundadır.
Bu nedenle sayfa numarası büyüdükçe sorgu doğrusal olarak yavaşlar.
İlk sayfada atlanacak kayıt yoktur ve sorgu anında biter; bu, sorunun geç fark edilmesine yol açar.
İkinci Sorun: Kayma
| Olay | Sonuç |
|---|---|
| Kullanıcı birinci sayfada | Normal |
| Yeni kayıt eklenir | Sıralama kayar |
| Kullanıcı ikinci sayfaya geçer | Bir kayıt tekrar görünür |
| Kayıt silinirse | Bir kayıt hiç görünmez |
Dördüncü satır sessiz bir veri kaybıdır: sayfalar arasında gezinirken araya kayıt eklenmesi veya silinmesi, kullanıcının bazı kayıtları iki kez görmesine veya hiç görmemesine yol açar — ve bunu kimse fark etmez.
Bu, yoğun güncellenen listelerde sürekli yaşanır.
Toplu işlem yapan betiklerde ise kayıt atlamak gerçek bir hataya dönüşür.
Atlama tabanlı sayfalama ile toplu işleme yapmak bu nedenle güvenilir değildir.
İmleç Yaklaşımı
Sayfa numarası yerine bir konum işaretçisi kullanılır:
- Son görülen kaydın değeri saklanır.
- Sonraki sorgu ondan büyükleri ister.
- Dizin doğrudan o noktaya atlar.
- Atlanan kayıt okunmaz.
Üçüncü madde performans farkını yaratır: dizin sayesinde veritabanı doğrudan başlangıç noktasına gider ve yalnızca istenen kayıtları okur — bininci sayfa ile birinci sayfa aynı hızda döner.
Maliyet artık sayfa numarasından bağımsızdır.
Dördüncü madde ise kayma sorununu da çözer. İşaretçi bir kayda bağlı olduğu için araya eklenen kayıtlar sıralamayı bozmaz.
Kullanıcı kaldığı yerden devam eder.
İmleç Alanı Seçimi
| Alan | Uygunluk |
|---|---|
| Artan kimlik | İdeal |
| Oluşturulma zamanı | Uygun, benzersizse |
| Ad veya başlık | Tekrar edebilir |
| Rastgele kimlik | Sıralanabilir değilse olmaz |
Üçüncü satır önemli bir kısıtı gösterir: imleç alanı benzersiz olmalıdır — aynı değere sahip iki kayıt varsa sınırda hangisinin dahil edileceği belirsizleşir ve kayıt atlanabilir veya tekrarlanabilir.
Çözüm, benzersiz olmayan bir alanla sıralarken ikinci bir alan eklemektir.
Tarih ve kimlik birlikte kullanıldığında hem istenen sıralama hem benzersizlik sağlanır.
Bu ikili sıralama için uygun bir bileşik dizin gerekir.
İmleç Sayfalamanın Sınırları
- Sayfa numarası gösterilemez.
- Rastgele sayfaya atlanamaz.
- Toplam sayfa sayısı bilinmez.
Bu üç sınır aynı kaynaktan doğar ve kabul edilmelidir: imleç yalnızca "buradan sonrası" bilgisini taşır — kaçıncı sayfada olduğunuzu bilmez ve doğrudan yüzüncü sayfaya gitmenizi sağlayamaz.
Bu nedenle klasik sayfa numarası arayüzü kullanılamaz.
Yerine "daha fazla yükle" veya sonsuz kaydırma deseni kullanılır.
Çoğu modern arayüz zaten bu yönde evrilmiştir ve kullanıcılar buna alışkındır.
Toplam Sayı Sorunu
| Yaklaşım | Maliyet |
|---|---|
| Her sorguda tam sayım | Çok pahalı |
| Yaklaşık sayım | Ucuz |
| Sayıyı önbelleklemek | Dengeli |
| Hiç göstermemek | Bedava |
Birinci satır çoğu kişinin fark etmediği bir yüktür: sayfalamada gösterilen toplam kayıt sayısı için yapılan sayım sorgusu, listeleme sorgusundan daha pahalı olabilir — filtreli bir sorguda veritabanı tüm eşleşmeleri saymak zorundadır.
Bu sayı genellikle kullanıcı için de çok değerli değildir.
Dördüncü satır ise en ucuz çözümdür ve modern arayüzlerde yaygınlaşmıştır.
İkinci satır ise büyük tablolarda kabul edilebilir bir yaklaşımdır; kesin sayı yerine tahmin gösterilir.
Karma Yaklaşım
- İlk sayfalarda atlama kullanın.
- Derin sayfalarda imlece geçin.
- Sınır belirleyin.
Bu yaklaşım kullanıcı arayüzünü korurken sorunu çözer: ilk birkaç sayfada klasik sayfa numaraları gösterilebilir çünkü orada atlama maliyeti düşüktür — derin sayfalara erişimi sınırlamak veya imlece geçmek ise felaketi önler.
Pratikte çok az kullanıcı beşinci sayfanın ötesine gider.
Derin sayfalara giden trafik genellikle otomatik tarayıcılardır.
Bu nedenle derin sayfa erişimini sınırlamak, gerçek kullanıcıları neredeyse hiç etkilemez.
API Tarafında
- İmleci opak bir değer olarak verin.
- İstemci onu yorumlamasın.
- Sonraki sayfa bağlantısı döndürün.
Birinci madde ileriye dönük esneklik sağlar: imleci kodlanmış ve anlamsız bir metin olarak sunmak, ileride sıralama alanını değiştirdiğinizde istemcileri kırmadan geçiş yapmanızı sağlar — istemci o değerin ne olduğunu bilmez, yalnızca geri gönderir.
Ham bir kimlik değeri sunarsanız istemciler ona bağımlı hâle gelir.
Üçüncü madde ise kullanımı basitleştirir. İstemci imleci kendisi birleştirmek yerine hazır bağlantıyı izler.
Bu, sayfalama mantığını tamamen sunucuda tutar.
Toplu İşlemede
- Atlama tabanlı sayfalama kayıt atlar.
- İmleç güvenilirdir.
- İşlenen kaydı işaretleyin.
Üçüncü madde ek bir güvence sağlar: toplu işlemede her kaydı işlendi olarak işaretlemek, sayfalama mantığından bağımsız olarak hiçbir kaydın atlanmamasını veya iki kez işlenmemesini garanti eder.
Bu, işlem yarıda kesildiğinde kaldığı yerden devam etmeyi de sağlar.
Birinci madde ise başta anlatılan kayma sorununun toplu işlemedeki karşılığıdır ve gerçek veri hatası üretir.
Milyonlarca kaydı işleyen bir betikte birkaç kaydın atlanması fark edilmez.
Büyük listeler ve toplu işlemler için yeterli veritabanı kaynağı gerekir; VDS barındırma altyapısı üzerinde bellek ve disk performansını iş yükünüze göre seçebilirsiniz.
Sonuç
Derin sayfalarda yavaşlamanın nedeni sezgiye aykırıdır: veritabanı atlanacak kayıtları hızlıca geçmez — onları da okur, sıralar ve sonra atar. İmleç tabanlı sayfalamada ise dizin doğrudan başlangıç noktasına gider ve bininci sayfa birinci sayfa kadar hızlıdır. Kayma sorununu da çözer: araya kayıt eklenmesi veya silinmesi, atlama tabanlı sayfalamada kullanıcının kayıtları iki kez görmesine veya hiç görmemesine yol açar.
Sıkça Sorulan Sorular (SSS)
Derin sayfalar neden yavaşlıyor?
Veritabanı atlanacak kayıtları hızlıca geçmez; onları da okur, sıralar ve sonra atar. Yüz bininci kayıttan başlayan bir sayfa için yüz bin kaydı işlemek zorundadır. İlk sayfada atlanacak kayıt olmadığı için sorun geç fark edilir.
Kullanıcı aynı kaydı iki kez görüyor?
Atlama tabanlı sayfalamanın kayma sorunu. Sayfalar arasında gezinirken araya kayıt eklenirse bir kayıt tekrar görünür, silinirse bir kayıt hiç görünmez. Toplu işlem yapan betiklerde bu, gerçek bir veri hatasına dönüşür.
İmleç sayfalamanın dezavantajı var mı?
Var: sayfa numarası gösterilemez, rastgele sayfaya atlanamaz ve toplam sayfa sayısı bilinmez. İmleç yalnızca "buradan sonrası" bilgisini taşır. Bu yüzden klasik sayfa numarası yerine "daha fazla yükle" deseni kullanılır.
Toplam kayıt sayısını göstermeli miyim?
Maliyetini bilerek karar verin. Filtreli bir sorguda sayım, listeleme sorgusundan daha pahalı olabilir çünkü veritabanı tüm eşleşmeleri saymak zorundadır. Bu sayı genellikle kullanıcı için de çok değerli değildir; hiç göstermemek veya önbelleklemek makul seçeneklerdir.