← Back to list

Paging vs Slice: Performans ve Kullanım Senaryoları

Büyük veri setlerini verimli şekilde sunmak kritik öneme sahiptir. Spring Data JPA, sayfalama için Page ve Slice sunar; ancak aralarındaki…

Hüsna Poyraz · 2026-02-13 18:42 · 52 claps · 4.6 min read
#paging #slice #java #spring-boot #performance
Open on Medium ↗
Wiki topics: 🔧 · Data Engineering

Paging vs Slice: Performans ve Kullanım Senaryoları

Büyük veri setlerini verimli şekilde sunmak kritik öneme sahiptir. Spring Data JPA, sayfalama için Page ve Slice sunar; ancak aralarındaki farkları anlamak, performansı ve kullanıcı deneyimini optimize etmek için anahtardır. Bu makale, ölçeklenebilir web uygulamalarında hangisinin ne zaman kullanılması gerektiğini açıklar.

İçindekiler

  1. Web Uygulamalarında Sayfalama Problemini Anlamak
  2. Page: Toplam Sayı Bilgisi ile Kapsamlı Görünüm
  3. Slice: Daha Hafif ve Verimli Alternatif
  4. Doğru Seçimi Yapmak: Performans, UX ve Gerçek Dünya Senaryoları

1. Web Uygulamalarında Sayfalama Problemini Anlamak

Binlerce veya milyonlarca kayıtla çalışırken, tüm veriyi çekmek; yavaş yükleme süreleri, yüksek bellek tüketimi ve kötü kullanıcı deneyimi nedeniyle pratik değildir. Sayfalama (Pagination), büyük veri setlerini daha küçük ve yönetilebilir “sayfalara” bölerek bu sorunu çözer.

Sayfalamanın faydaları:

  • Geliştirilmiş Performans: Veri transferini ve işlem yükünü azaltır.
  • Daha İyi Kullanıcı Deneyimi: Bilgi yüklenmesini önler, kademeli gezinmeye olanak tanır.
  • Kaynak Verimliliği: Sunucu ve istemci bellek kullanımını minimize eder.

Spring Data JPA’daki Pageable arayüzü; sayfa numarası, sayfa boyutu ve sıralama düzeni bilgilerini kapsayarak sayfalama gereksinimlerini tanımlar.

Pageable kullanan örnek repository metodu:

public interface UserRepository extends JpaRepository<User, Long> {
    List<User> findByActiveTrue(Pageable pageable);
}

findByActiveTrue metodu Pageable ile çağrıldığında, Spring Data otomatik olarak SQL sorgusuna LIMIT ve OFFSET ekler.

Pageable pageable = PageRequest.of(0, 10, Sort.by("lastName").ascending());
userRepository.findByActiveTrue(pageable); 
// İlk 10 aktif kullanıcıyı getirir

Dönüş tipi olarak Page veya Slice seçimi, uygulamanın davranışı ve veritabanı yükü üzerinde önemli etkiye sahiptir.

2. Page: Toplam Sayı Bilgisi ile Kapsamlı Görünüm

Page, mevcut sayfanın içeriğiyle birlikte tüm veri setine ilişkin kapsamlı meta veriler sağlar. Genellikle “Sayfa 1 / 10” veya toplam öğe sayısını gösteren geleneksel sayfalama arayüzlerinde kullanılır.

Page Nedir?

org.springframework.data.domain.Page, aşağıdaki bilgileri sağlayan zengin bir nesnedir:

  • getContent(): Mevcut sayfadaki entity listesi
  • getTotalElements(): Tüm sayfalardaki toplam öğe sayısı
  • getTotalPages(): Toplam sayfa sayısı
  • getNumber(): Mevcut sayfa numarası
  • getSize(): İstenen sayfa boyutu
  • hasNext(), hasPrevious(), isFirst(), isLast(): Gezinme yardımcı metodları

Gizli Maliyet: Toplam Sayı (COUNT) Sorgusu

totalElements ve totalPages bilgilerini sağlayabilmek için Page, iki ayrı veritabanı sorgusu çalıştırır:

  1. Sayfa içeriğini almak için ana sorgu (LIMIT ve OFFSET)
  2. Toplam öğe sayısını belirlemek için ayrı bir COUNT(*) sorgusu

Örnek repository ve servis kullanımı:

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;

public interface ProductRepository extends JpaRepository<Product, Long> {
    Page<Product> findByCategory(String category, Pageable pageable);
}
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

@Service
public class ProductService {
    private final ProductRepository productRepository;
    public ProductService(ProductRepository productRepository) {
        this.productRepository = productRepository;
    }
    public Page<Product> getProductsByCategory(String category, int page, int size) {
        Pageable pageable = PageRequest.of(page, size, Sort.by("name").ascending());
        Page<Product> productPage = productRepository.findByCategory(category, pageable);
        System.out.println("Toplam ürün: " + productPage.getTotalElements());
        System.out.println("Toplam sayfa: " + productPage.getTotalPages());
        return productPage;
    }
}

SQL loglarında şunlar görülür:

-- Sorgu 1: İçeriği getir
SELECT ... FROM product p WHERE p.category = ? ORDER BY p.name ASC LIMIT ? OFFSET ?;
-- Sorgu 2: Toplam sayıyı getir
SELECT COUNT(p.id) FROM product p WHERE p.category = ?;

Page Ne Zaman Kullanılmalı?

  • Geleneksel Sayfalama Arayüzleri: “Sayfa X / Y” veya toplam sayı gösterilecekse
  • Raporlama / Analitik: Filtrelenmiş veri setinin tamamını göstermek gerekiyorsa
  • Küçük Veri Setleri: COUNT(*) sorgusunun maliyeti önemsizse

Çok büyük tablolar veya karmaşık sorgularda COUNT(*) işlemi pahalı olabilir ve performans darboğazına yol açabilir.

3. Slice: Daha Hafif ve Verimli Alternatif

Slice, daha hafif bir alternatiftir ve toplam sayıyı değil, yalnızca daha fazla veri olup olmadığını bilmesi gereken modern arayüzler için idealdir (örneğin infinite scroll veya “Daha Fazla Yükle” butonu).

Slice Nedir?

org.springframework.data.domain.Slice, mevcut içeriğe ve bir sonraki dilimin varlığına odaklanır. Şunları sağlar:

  • getContent(): Mevcut dilimdeki entity listesi
  • getNumber(): Mevcut sayfa numarası
  • getSize(): İstenen sayfa boyutu
  • hasNext(), hasPrevious(): Önceki veya sonraki dilim kontrolü

📍Önemli olarak, Slice **getTotalElements() veya getTotalPages() sağlamaz.**

Performans Avantajı: Toplam Sayı Sorgusu Yok

Slice, ayrı bir COUNT(*) sorgusu çalıştırmaz; bu da özellikle büyük veri setlerinde ciddi performans kazancı sağlar.

hasNext() bilgisini sağlayabilmek için Slice, N kayıt istendiğinde aslında N + 1 kayıt çeker. Eğer N + 1 kayıt dönerse, hasNext() değeri true olur (fazladan kayıt atılır). Eğer N + 1’den az kayıt dönerse, hasNext() değeri false olur.

SQL loglarında yalnızca tek sorgu görülür:

-- Sorgu 1: Mevcut dilimin içeriğini ve bir fazla kaydı getir
SELECT ... FROM comment c WHERE c.post_id = ? ORDER BY c.created_at DESC LIMIT ? OFFSET ?;
-- Buradaki LIMIT (size + 1) olur, örneğin size 10 ise 11.

Slice Ne Zaman Kullanılmalı?

  • Infinite Scroll: Kullanıcı aşağı kaydırdıkça veri yüklenen akışlar
  • “Daha Fazla Yükle” Butonları: Bir sonraki veri grubunu getiren butonlar
  • API Endpoint’leri: Mobil / SPA istemcilerin yalnızca mevcut veriyi ve “daha fazlası var mı?” bilgisini istemesi durumunda
  • Çok Büyük Veri Setleri: COUNT(*) işleminin çok yavaş olacağı durumlarda
  • Performans Kritik Senaryolar: Veritabanı sorgularını minimize etmek öncelikse

Slice, kapsamlı meta veriden feragat ederek özellikle yüksek hacimli verilerde önemli performans kazanımı sağlar.

4. Doğru Seçimi Yapmak: Performans, UX ve Gerçek Dünya Senaryoları

Page ve Slice arasındaki seçim; kullanıcı deneyimi gereksinimleri, veri hacmi ve performans ihtiyaçlarına bağlıdır.

Performans Değerlendirmesi

  • **Page (COUNT(*) ile):**
  • Ek Yük: Her istek için iki veritabanı sorgusu
  • Ölçeklenebilirlik: Büyük tablolar veya karmaşık sorgularda COUNT(*) darboğaz oluşturabilir
  • Veritabanı Yükü: Sayfalı endpoint’lerde sorgu yükünü ikiye katlar
  • **Slice (COUNT(*) olmadan):**
  • Verimlilik: Her istek için tek veritabanı sorgusu (pageSize + 1 kayıt)
  • Ölçeklenebilirlik: COUNT(*) işlemi olmadığı için büyük veri setlerinde daha ölçeklenebilir
  • Veritabanı Yükü: Page’e kıyasla yükü yarıya indirir

Kullanıcı Deneyimi (UX) Etkisi

  • **Page Arayüzleri:**
  • Artılar: Toplam öğe ve sayfa bilgisi ile net bağlam sunar; belirli sayfalara atlama imkanı verir. Geleneksel masaüstü veya admin arayüzleri için idealdir.
  • Eksiler: Daha az dinamik, açık gezinme gerektirir.
  • **Slice Arayüzleri:**
  • Artılar: Infinite scroll veya “Daha Fazla Yükle” gibi akıcı deneyimler sunar; mobil ve modern web uygulamalarında popülerdir. Algılanan hız daha yüksektir.
  • Eksiler: Kullanıcı toplam öğe veya sayfa sayısını bilmez; bağlamın kritik olduğu durumlarda dezavantaj olabilir.

En İyi Uygulamalar ve Yaygın Hatalar

  • Aksi açıkça gerekmiyorsa varsayılan olarak Slice kullanın: Toplam sayı gösterilmeyecekse genellikle daha performanslıdır.
  • **Pageable içinde her zaman ORDER BY kullanın:** Tutarlı ve stabil sayfalama için gereklidir; aksi halde kayıt atlama veya tekrar etme olabilir.
Pageable pageable = PageRequest.of(0, 10, Sort.by("id").ascending()); 
// Doğru // Pageable pageable = PageRequest.of(0, 10); // Yanlış
  • **Slice ile toplam sayıyı “hack” etmeye çalışmayın:** totalElements gerekiyorsa Page kullanın.
  • **Pageable.unpaged() kullanımına dikkat edin:** Büyük veri setlerinde sayfalamayı devre dışı bırakmak risklidir.
  • Veritabanı indekslerini göz önünde bulundurun: WHERE ve ORDER BY kolonlarını uygun şekilde indekslemek performans için kritiktir.

Gerçek Dünya Senaryoları

  • E-ticaret Ürün Listeleme: “Sayfa 1 / 25” gibi bir yapı için Page uygundur.
  • Sosyal Medya Akışı: Infinite scroll için Slice idealdir.
  • Admin Paneli Kullanıcı Listesi: Toplam kullanıcı sayısı ve sayfa atlama gerekiyorsa Page uygundur.
  • Mobil Uygulama API’si: Bildirimleri partiler halinde çekerken Slice daha performanslıdır.

Gereksinimleri dikkatlice değerlendirmek, Spring Data’nın sayfalama özelliklerini yüksek performanslı ve kullanıcı dostu uygulamalar geliştirmek için doğru şekilde kullanmayı sağlar.

Page ve Slice arasındaki fark, API seçimlerinin performans ve ölçeklenebilirlik üzerindeki etkisine klasik bir örnektir. Geleneksel arayüzler için toplam sayı bilgisi gerekiyorsa Page kullanın ve COUNT(*) maliyetini kabul edin. Infinite scroll veya “daha fazlası var mı?” bilgisinin yeterli olduğu senaryolarda ise Slice tercih ederek veritabanınızı pahalı işlemlerden koruyun. Doğru aracı doğru yerde kullanarak uygulamanızın duyarlı ve verimli kalmasını sağlayın.

Etiketler: java spring spring-boot pagination slice page performance software-engineering software-development jpa spring-data

Kaynaklar:

  • Spring Data JPA Dokümantasyonu — Query methods
  • Baeldung — Spring Data JPA Pagination

Faydalı bulduysanız takip edin, alkışlayın ve paylaşın.


메타데이터
post_id
f0cf49d0e4e8
slug
paging-vs-slice-performans-ve-kullanım-senaryoları-f0cf49d0e4e8
url
https://medium.com/@husnapoyraz88/paging-vs-slice-performans-ve-kullan%C4%B1m-senaryolar%C4%B1-f0cf49d0e4e8
canonical_url
https://medium.com/@husnapoyraz88/paging-vs-slice-performans-ve-kullan%C4%B1m-senaryolar%C4%B1-f0cf49d0e4e8
author_url
https://medium.com/@husnapoyraz88
status
ok
fetched_at
2026-07-13 06:23:13