Sessiz Veritabanı Katili
B2B SaaS platformları geliştirirken, en yaygın veritabanı performans sorunlarından biri, korkulu rüya olan N+1 Query Problemdir. Bu, geliştiricilerin bir kayıt listesi alıp ardından önceden eager-load edilmemiş bir ilişkiye erişmek için döngüye girdiğinde meydana gelir.
Bir kontrol panelinde 50 faturayı görüntülediğinizi ve bunlardan her birinin müşteri şirket adını yazdırmak için döngüye girdiğinizi düşünün: $invoice->client->name. İlk sorgunuza ->with('client') eklemeyi unuttuysanız, Eloquent 51 sorguyu çalıştırır: faturaları almak için 1 sorgu ve ardından her bir müşteri için 50 ayrı sorgu. Yerel bir geliştirme ortamında bu 51 sorgu 10 milisaniye içinde çalışır ve tamamen gözden kaçar. Ancak üretim ortamında yoğun trafik altında, bu N+1 çığlığı anında veritabanı bağlantı havuzunuzu tüketir ve sunucuyu çökertebilir.
Kurumsal Çözüm: Proaktif Uygulama
Kayıp eager load’ları tespit etmek için tamamen kod incelemelerine güvenemezsiniz. Mimari çözüm, geliştiricilerin ilk etapta N+1 sorguları yazmalarını fiziksel olarak engellemek için framework’ü yapılandırmaktır.
Laravel, Strict Mode adı verilen güçlü bir mimari koruma sunar. Model::preventLazyLoading() uygulama düzeyinde zorlandığında, Laravel veritabanı ilişkilerinizi aktif bir şekilde izler. Framework, yerel geliştirme veya test sırasında bir lazy load (N+1 sorgu) tespit ederse, ölümcül bir LazyLoadingViolationException fırlatarak sayfayı bozar ve geliştiriciyi kodu hemen düzeltmeye zorlar.
Adım 1: Koruma Mekanizmasını Tasarlamak
Bu güvenlik mekanizmasını AppServiceProvider içinde küresel olarak yapılandırıyoruz. Kritik olarak, yalnızca yerel ve test ortamlarımızda ölümcül hatalar fırlatıyoruz. Eğer bir N+1 sorgusu bir şekilde üretime sızarsa, kullanıcı kontrol panelini çökertmek yerine onu nazikçe günlüğe kaydediyoruz.
namespace App\Providers;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function boot(): void
{
// 1. N+1 Sorgularını Önlemek
// Geliştirme/test ortamında bir hata fırlatır, fakat üretimde nazikçe günlüğe kaydeder
Model::preventLazyLoading(! app()->isProduction());
// 2. Sessiz Kütle Atama Hatalarını Önlemek
// Modelin $fillable dizisinde tanımlanmamış bir sütunu kaydetmeye
// çalışırsa bir hata fırlatır.
Model::preventSilentlyDiscardingAttributes(! app()->isProduction());
// 3. Kayıp İlişkilerde Bellek Sızıntılarını Önlemek
// Müşteri silinirse $invoice->client->name null döndürmez,
// veri bütünlüğünü zorlar.
Model::preventAccessingMissingAttributes(! app()->isProduction());
}
}
Adım 2: Üretimde Nazik Günlükleme
Üretimde kırılma olmaksızın görünürlük sağlamak için, Laravel’in bu ihlalleri nasıl işlediğini özelleştirebiliriz.
use Illuminate\Database\Eloquent\Model;
public function boot(): void
{
Model::handleLazyLoadingViolationUsing(function ($model, $relation) {
$class = get_class($model);
// Bu durumu doğrudan özel bir Slack veya Discord telemetri kanalına göndermek
\Log::warning("Üretimde N+1 Sorgu Tespit Edildi: Model [{$class}] üzerinde [{$relation}] lazy load etmeye çalışıldı.");
});
}
Mühendislik ROI’si
Strict Mode’u uygulama sağlayıcınızda zorlayarak, veritabanı optimizasyonunu geliştirme pipeline’ınızın en başına kaydırırsınız. N+1 sorguları birleştirmek imkansız hale gelir. Kod tabanınız doğal olarak son derece optimize olur ve üretimde PostgreSQL veritabanlarınız yalnızca temiz, toplu ve eager-loaded sorgular alır.
Kaynak: Orijinal Makale


