Performans Düşüren: OFFSET
<p>Veri ağırlıklı B2B SaaS platformları geliştirirken, örneğin denetim günlükleri, sonsuz kaydırma aktivite beslemeleri veya büyük fatura tabloları oluştururken, pagination (sayfalama) zorunludur. Laravel'deki varsayılan yaklaşım, <code>paginate()</code> metodunu kullanmaktır. Arka planda, bu standart SQL <code>LIMIT</code> ve <code>OFFSET</code> kullanır.</p>
<p>İlk birkaç sayfa için <code>OFFSET</code> mükemmel çalışır. Ancak bir kullanıcı denetim kayıtlarınızın 1,000. sayfasına geçtiğinde ne olur? Veritabanı sorgusu şu şekilde görünür: <code>SELECT * FROM audit_logs ORDER BY created_at DESC LIMIT 15 OFFSET 15000</code>. Bunu yürütmek için PostgreSQL, sorgulanan 15 satırı verebilmek için önce 15,000 satırı sıralı bir şekilde tarayıp almak ve sonrasında atmak zorundadır. Tablo sayılarınız milyonlara ulaştıkça, derin offset sorguları CPU'nuzu darboğaz yapar ve API'nizi çökertebilir.</p>
<h2>Kurumsal Çözüm: Cursor Pagination</h2>
<p>Sonsuz ölçeklenebilirliği destekleyen platformlar oluşturmak için offset pagination'dan vazgeçmeli ve <strong>Cursor Pagination</strong> (anahtar seti sayfalama olarak da bilinir) benimsemeliyiz.</p>
<p>Veritabanına "15,000 satırı atla" yerine, cursor pagination, önceki sayfanın son satırından benzersiz bir tanımlayıcı (cursor) geçirir. Sorgu şu hale gelir: <code>SELECT * FROM audit_logs WHERE id .</code> Çünkü <code>id</code> sütunu indekslidir, veritabanı bu satıra bellek üzerinde doğrudan geçiş yapar ve önceki kayıtları taramak zorunda kalmaz. Performans, 1. sayfada olsanız bile 10,000. sayfada olsanız bile her zaman milisaniyelere dayanır.</p>
<h3>Laravel'de Cursor Pagination Uygulama</h3>
<p>Laravel, cursor pagination'a geçişi son derece zarif hale getirir. Gerçek sorgu mantığınıza neredeyse sıfır değişiklik gerektirir.</p>
<pre><code>namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Models\AuditLog;
use Illuminate\Http\Request;
class AuditLogController extends Controller
{
/
Yüksek performanslı cursor pagination kullanarak logları getir.
*/
public function index(Request $request)
{
// ❌ ANTI-PATTERN: Offset Pagination
// Kullanıcı derinleştikçe yavaşlar.
// $logs = AuditLog::where(‘tenant_id’, $request->user()->tenant_id)
// ->orderBy(‘id’, ‘desc’)
// ->paginate(15);// ✅ KURUMSAL PATTERN: Cursor Pagination
// Performans derinlikten bağımsız olarak sabittir O(1).
$logs = AuditLog::where(‘tenant_id’, $request->user()->tenant_id)
->orderBy(‘id’, ‘desc’)
->cursorPaginate(15);return response()->json($logs);
}
}
<h2>Cursorların Dezavantajları</h2>
<p>Cursor pagination, sonsuz kaydırma ve büyük veri kümeleri için mükemmel olsa da, belirli mimari dezavantajları vardır:</p>
<ul>
<li>
<strong>Sayfa Numaraları Yok:</strong> Kullanıcılara "Sayfa 5/100" gösteremezsiniz. Sadece "Sonraki" ve "Önceki" butonlarını sağlayabilirsiniz. Sonsuz kaydırma içeren beslemeler (Twitter veya Slack gibi) için bu oldukça uygundur.</li>
<li>
<strong>Kesin Sıralama:</strong> Cursor'ların referans noktasını korumak için benzersiz ve sıralı bir sütuna (otomatik artan <code>id</code> veya benzersiz <code>created_at</code> zaman damgası gibi) göre sıralama yapmalısınız.</li>
</ul>
<h2>Sonuç</h2>
<p>B2B SaaS uygulamalarınızda sonsuz kaydırma veya büyük veri tabloları varsa, varsayılan offset pagination'a güvenmek, mimari bir hata demektir. Laravel’in <code>cursorPaginate()</code> metoduna geçiş yaparak, yükü veritabanı CPU'sundan uzaklaştırır ve indekslerinizi doğru bir şekilde kullanarak, API'nizin herhangi bir ölçekte hızlı kalmasını sağlarsınız.</p>Kaynak: Orijinal Makale


