İlk N Kayıt ve Sayfalama: LIMIT, TOP, OFFSET Kullanımı
Beceri rehberi

İlk N Kayıt ve Sayfalama: LIMIT, TOP, OFFSET Kullanımı

Hazırlayan: Mindset Institute EditörlüğüGüncellendi: 5 dk okuma

İlk N kaydı getirmek için LIMIT, TOP ve FETCH FIRST farkını, OFFSET ile sayfalamayı, ORDER BY zorunluluğunu ve büyük tablolarda performansı öğrenin.

Neden sonuç sayısını sınırlarız?

Bir sorgu, koşulu sağlayan tüm satırları döndürür. Milyonlarca satırlık bir tabloda bunların hepsini çekmek hem sunucuyu hem ağı hem de ekranı gereksiz yorar. Sonuç sayısını sınırlamak şu tipik ihtiyaçlardan doğar: tablonun nasıl göründüğüne hızlıca bakmak, en yüksek ya da en düşük değerli kayıtları listelemek ve uygulamada sonuçları sayfa sayfa göstermek.

Her veritabanı sistemi bu işi kendi yöntemiyle yapar ve sözdizimi aynı değildir. MySQL, PostgreSQL ve SQLite'ta LIMIT, SQL Server ve Access'te TOP, Oracle'ın yeni sürümlerinde ve SQL standardında FETCH FIRST kullanılır. SQL standardındaki OFFSET ... FETCH biçimi ise SQL Server, PostgreSQL ve Oracle'da bulunur. Çalıştığınız sistemin dokümantasyonuna bakıp desteklenen biçimi seçin.

Temel kural, hangi yöntemi kullanırsanız kullanın sıralamanın açık belirtilmesidir. Aksi halde hangi satırların döndüğü belirsizdir.

ORDER BY olmadan ilk N kayıt anlamsızdır

İlişkisel veritabanında satırların doğal bir sırası yoktur. Sorguya ORDER BY eklemezseniz sistem satırları kendi bulduğu sırayla döndürür; bu sıra aynı sorguda bile zamanla değişebilir. Dolayısıyla ORDER BY olmadan LIMIT ya da TOP kullanmak, rastgele bir alt küme almak demektir. Tabloya göz atmak için bu kabul edilebilir, ancak rapor ve uygulama sorgularında kabul edilemez.

Örneğin en yüksek tutarlı siparişleri listelemek için siparişleri tutara göre azalan sıralar, sonra ilk satırları alırsınız. Sıralama ölçütünüz tekrar eden değerler içeriyorsa sonuç belirsizleşir: aynı tutarlı birçok sipariş varsa hangisinin sınır içinde kalacağı kesin olmaz. Çözüm, sıralamaya benzersiz bir ek sütun, örneğin kimlik sütununu eklemektir. Bu şekilde her çalıştırmada aynı sonuç gelir.

SQL Server'da WITH TIES seçeneği, sınırdaki eşit değerli satırların hepsini birlikte döndürmeye izin verir. Sınırdaki eşitlikleri dışlamak istemiyorsanız bu seçenek anlamlıdır; döndürülen satır sayısı istenenden fazla olabilir.

Sistemlere göre söz dizimi

Aynı işi farklı sistemler farklı yazar. MySQL, PostgreSQL ve SQLite: sorgunun sonuna LIMIT ve ardından döndürülecek satır sayısı yazılır; atlama için OFFSET eklenir. MySQL'de LIMIT içinde atlama ve sayı virgülle ayrılarak da yazılabilir, ancak okunabilirlik için OFFSET tercih edilir.

SQL Server: SELECT'ten hemen sonra TOP ve satır sayısı gelir. Sayfalama için ORDER BY'dan sonra OFFSET ... ROWS FETCH NEXT ... ROWS ONLY biçimi vardır ve bu kullanım için ORDER BY zorunludur. TOP ile yüzde de belirtilebilir (TOP ... PERCENT).

Oracle ve SQL standardı: FETCH FIRST ... ROWS ONLY, ORDER BY'dan sonra yazılır. Eski Oracle sürümlerinde ROWNUM sözde sütunu kullanılırdı; ancak ROWNUM sıralamadan önce uygulandığı için doğru sonuç almak adına sıralamayı iç sorguda yapmak gerekir.

Kalıpları bir kenara not etmek faydalıdır, çünkü sistem değiştirdiğinizde sorgu bozulur. Birden çok sistemi destekleyen uygulamalar çoğunlukla bu farkları bir kitaplık ya da veri erişim katmanıyla soyutlar.

Sayfalama: OFFSET nasıl çalışır?

Sayfalama, sonucu sabit boyutlu parçalara bölerek göstermektir. Mantık şöyledir: sayfa boyutu satır sayısı olarak belirlenir; ilk sayfa için atlama sıfır, sonraki sayfalar için atlama, önceki sayfaların toplam satır sayısı kadar olur. Yani sayfa numarasından bir çıkarıp sayfa boyutuyla çarparsınız; çıkan değer OFFSET'e, sayfa boyutu LIMIT ya da FETCH NEXT'e yazılır.

Örneğin bir ürün listesi sayfasında satırlar fiyata göre sıralanıyor olsun. Uygulama sayfa numarasını ve boyutunu parametre olarak sorguya gönderir, sorgu ORDER BY, OFFSET ve LIMIT ile ilgili dilimi getirir. Toplam sayfa sayısını göstermek için ayrıca COUNT sorgusu çalıştırılır; bu ek sorgu büyük tablolarda maliyetlidir.

Sayfalamada sıralamanın deterministik olması şarttır. Benzersiz olmayan bir sütuna göre sıralama, sayfalar arasında aynı satırın tekrar görünmesine ya da hiç görünmemesine yol açabilir. Çözüm yine benzersiz bir ek sıralama sütunudur.

OFFSET'in yavaşlama sorunu ve keyset sayfalama

OFFSET basit ve kolaydır, ama derin sayfalarda yavaşlar. Sistem atlanacak satırları yine de okuyup sayması gerektiğinden, çok ileri bir sayfa istendiğinde önceki tüm satırlar işlenir. Büyük tablolarda ve çok sayfalı listelerde yanıt süresi sayfa numarasıyla artar.

Keyset (arama temelli) sayfalama bu sorunu çözer. Atlama kullanmak yerine önceki sayfanın son satırındaki sıralama değerini alıp bir sonraki sayfa için bu değerden büyük olan satırları filtrelersiniz: WHERE kimlik koşulu önceki son kimlikten büyük olacak biçimde, ORDER BY kimlik ve LIMIT ile. Sıralama sütunu indeksliyse sistem doğrudan o noktadan başlar ve sayfa derinliği önemini yitirir.

Bedeli, rastgele sayfaya atlayamamaktır; yalnızca ileri ve geri gidilebilir. Sonsuz kaydırmalı listelerde ve API'lerde bu kabul edilebilir, 'sayfa numarasına git' özelliği gerekiyorsa OFFSET'ten vazgeçmek zor olur. Seçim kullanım şekline bağlıdır.

Örnek kullanımlar ve sık yapılan hatalar

Yaygın kullanım örnekleri: • En çok satan ürünleri listelemek: satış tutarına göre azalan sıralayıp ilk satırları almak. • Bir tablonun yapısına bakmak: veri sınırsız çekilmeden küçük bir örnek almak. • Son eklenen kayıtlar: oluşturma tarihine göre azalan sıralayıp sınırlamak. • Her grubun en yüksek kaydı: bu iş LIMIT ile değil, ROW_NUMBER gibi pencere fonksiyonuyla yapılır; çünkü LIMIT sorgu genelini sınırlar, grup başına değil.

Sık hatalar: • ORDER BY yazmayı unutmak ya da benzersiz olmayan sütunla sıralamak. • LIMIT ile WHERE arasındaki sırayı karıştırmak: sınır filtreden sonra uygulanır, filtrelenmiş sonuçtan ilk satırlar alınır. • SQL Server'da sayfalama için TOP kullanmaya çalışmak; bunun yerine OFFSET FETCH tercih edilmelidir. • Sayıyı parametre yerine metin birleştirmesiyle sorguya yazmak; parametreli sorgu kullanın. • Toplam sayfa sayısı için her seferinde tabloyu baştan saymak.

Mindset kataloğunda SQL ile Veri Sorgulama (Temel) eğitimi Filtreleme Teknikleri ve Temel Fonksiyonlar ile Pratik İş Raporları ile Sorgu Geliştirme modüllerini, SQL ile Programlama Eğitimi ise Sorgular modülünü içerir. Bu modüller, rapor ve panel hazırlayan analist ekipleri için uygundur.

İlgili Mindset programı

SQL ile Veri Sorgulama (Temel)

Sık sorulanlar

Sık sorulan sorular

LIMIT ile TOP arasındaki fark nedir?

Her biri sonuç sayısını sınırlar, ancak farklı sistemlerde kullanılır. LIMIT MySQL, PostgreSQL ve SQLite'ta sorgunun sonuna, TOP ise SQL Server'da SELECT'ten hemen sonra yazılır. İşlev aynıdır; sözdizimi farklıdır. Sistemler arası taşınabilirlik için SQL standardındaki FETCH FIRST de seçenek olabilir.

OFFSET FETCH için ORDER BY zorunlu mu?

SQL Server'da OFFSET ve FETCH kullanıldığında ORDER BY zorunludur; olmadan sorgu hata verir. Diğer sistemlerde zorunlu olmasa da sıralamasız sayfalama anlamsızdır, çünkü sayfalar arasında satırlar tekrar edebilir ya da kaybolabilir. Her zaman açık ve benzersiz bir sıralama kullanın.

Rastgele kayıt nasıl getirilir?

Sisteme özel yöntemler vardır: PostgreSQL ve SQLite'ta ORDER BY RANDOM(), MySQL'de ORDER BY RAND(), SQL Server'da ORDER BY NEWID() sonrasında sınırlama yapılır. Bu yaklaşım tüm tabloyu sıralar, bu nedenle büyük tablolarda yavaştır; büyük veride örnekleme için sistemin sunduğu özel örnekleme özelliklerine bakın.

Sayfalama sırasında yeni kayıt eklenirse ne olur?

OFFSET temelli sayfalamada araya yeni kayıt girerse satırlar kayar; bir sonraki sayfada aynı kayıt tekrar görünebilir ya da bir kayıt atlanabilir. Keyset sayfalama, önceki sayfanın son değerinden devam ettiği için bu kaymaya karşı daha dayanıklıdır.

Yalnızca en yüksek değerli tek kaydı almak için LIMIT mi MAX mı?

Yalnızca değeri istiyorsanız MAX yeterlidir. Değerin yanında kaydın diğer sütunları da gerekiyorsa değere göre azalan sıralayıp tek satırla sınırlamak gerekir. Eşit değerli birden çok kayıt olabilecekse WITH TIES ya da pencere fonksiyonları daha doğru sonucu verir.