aslain.dev
0%
01 Hizmetler 02 Hakkımda 03 Projeler 04 Stack 05 Blog 06 İletişim
← Tüm makaleler Web Geliştirme

Eloquent vs Query Builder: Ne Zaman Hangisi

Laravel'de veri katmanını kurarken karşına çıkan ilk büyük karar, Eloquent ORM ile query builder arasındadır; eloquent query builder ikilisi aslında aynı temele oturur ama farklı soyutlama seviyelerinde çalışır. Eloquent, tabloları model nesnelerine bağlar ve ilişkileri, olayları, mutator'ları getirir. Query builder ise akıcı bir arayüzle SQL'e çok daha yakın durur. Hangisinin "doğru" olduğu sorusunun tek bir cevabı yok: doğru cevap, o anki işin ne olduğuna bağlı.

İkisi de aynı çekirdeği paylaşır

Önemli bir nokta: Eloquent, query builder'ın üzerine kurulmuştur. Bir model üzerinde where() çağırdığında aslında arka planda bir query builder örneğine ulaşırsın. Yani Eloquent "yavaş bir alternatif" değil, query builder'a nesne katmanı, ilişki yönetimi ve model olayları ekleyen bir üst seviyedir. Performans farkı motorun kendisinden değil, bu ek katmanın yaptığı işten doğar: her satırı bir PHP nesnesine dönüştürmek (hydration) ve ilişkileri yönetmek bedel ister.

Eloquent ne zaman parlar

Eloquent, iş mantığının merkezinde olduğun, az-orta sayıda kaydı okuyup yazdığın CRUD senaryolarında açık ara öne çıkar. Okunabilirlik ve bakım kolaylığı buradaki asıl kazanç:

  • İlişkiler: $user->posts gibi tek satırla ilişkili veriye ulaşırsın; with() ile eager loading yaparak N+1 sorgu problemini çözersin.
  • Model olayları: creating, saved gibi olaylar, observer'lar ve mutator/cast'lar otomatik çalışır.
  • Soft delete, timestamps, scope'lar: Çoğu tekrar eden mantık trait ve scope ile tek yerde toplanır.
// Eager loading ile N+1'i önle
$posts = Post::with('author', 'comments')
    ->where('published', true)
    ->latest()
    ->get();

foreach ($posts as $post) {
    echo $post->author->name; // ek sorgu yok
}

Query builder ne zaman daha iyi

Query builder, model davranışına ihtiyacın olmadığında ve performansın kritik olduğunda devreye girer. Binlerce satırlık raporlar, toplu güncellemeler, karmaşık join ve aggregate sorguları tam onun alanıdır. Her satırı model nesnesine çevirmediği için bellek ve CPU açısından daha hafiftir.

// Doğrudan, hafif bir raporlama sorgusu
$stats = DB::table('orders')
    ->select('user_id', DB::raw('SUM(total) as toplam'))
    ->where('created_at', '>=', now()->subMonth())
    ->groupBy('user_id')
    ->having('toplam', '>', 1000)
    ->get();

Burada model nesnesi, ilişki ya da olay zaten istemiyorsun; sadece sayıları toplayıp dönmek istiyorsun. Query builder bu işi hydration yükü olmadan yapar ve stdClass nesneleri döndürür.

Performans dengesini sayılarla düşün

Pratikte fark çoğu zaman tek bir kaydı çekerken hissedilmez; mesele ölçektedir. 50 satırı Eloquent ile çekmek ile query builder ile çekmek arasında ölçülebilir bir uçurum olmaz. Ama 50.000 satırı bir export işi için döngüye sokuyorsan, her satır için model oluşturmak ciddi bellek tüketir. Birkaç pratik kural:

  • Büyük okuma + işleme: Query builder ya da Eloquent'in cursor()/lazy() yöntemleriyle satırları akıt, hepsini belleğe alma.
  • Toplu güncelleme: Model::where(...)->update([...]) tek sorguyla çalışır ama model olaylarını tetiklemez; bunu bilerek kullan.
  • Sadece birkaç sütun lazımsa: Eloquent'te bile select() ile sütun sınırla; gereksiz veri çekmek hydration'ı yavaşlatır.
// 50.000 satırı belleğe yığmadan işle
Order::where('exported', false)
    ->lazy()
    ->each(function ($order) {
        // her seferinde tek model, düşük bellek
    });

İkisini birlikte kullanmak en gerçekçi yol

Doğru/yanlış ikilemi yerine, çoğu proje ikisini birlikte kullanır. Aynı uygulamada CRUD ve form işlemlerini Eloquent'le yazıp, ağır dashboard sorgularını query builder'a bırakmak tamamen normaldir. Hatta Eloquent içinde whereRaw() veya selectRaw() ile gerektiği yerde ham SQL'e inebilir, model avantajlarını korurken performansı ayarlayabilirsin. Ham sorguya inerken parametre bağlamayı (binding) ihmal etme; whereRaw('price > ?', [$min]) gibi kullanım SQL injection'a karşı korur.

Karar verirken sorulacak sorular

  • İlişkiler, olaylar veya cast'lar bu işte gerekli mi? Gerekliyse Eloquent.
  • Kaç satır dönecek ve hepsini nesneye mi çevireceğim? Çoksa query builder ya da lazy().
  • Bu kod sıcak bir yol mu (her istekte mi çalışıyor)? Sıcaksa ölç ve gerekirse sadeleştir.
  • Okunabilirlik mi yoksa milisaniye mi daha değerli? Çoğu ekran için okunabilirlik kazanır.

Sık Sorulan Sorular

Eloquent gerçekten query builder'dan yavaş mı?

Tek başına motor değil, her satırı PHP nesnesine dönüştürme (hydration) ve ilişki yönetimi yavaşlatır. Az kayıtta fark hissedilmez; binlerce satırda query builder belirgin biçimde daha hafiftir.

Eloquent içinde ham SQL kullanabilir miyim?

Evet. whereRaw(), selectRaw(), DB::raw() ile ham parça ekleyebilirsin. Değerleri mutlaka parametre bağlama ile geçir, doğrudan string birleştirme yapma.

Hangisi varsayılan tercihim olmalı?

Eloquent ile başla; kod daha temiz ve bakımı kolay olur. Profil çıkarınca darboğaz bulduğun yerlerde o sorguyu query builder'a ya da akış tabanlı yönteme taşı.

Laravel uygulamanın veri katmanı yavaş mı, yoksa kafan mı karışık? Eloquent ve query builder'ı doğru yerlerde kullanan, ölçeklenebilir bir mimari kurmana yardımcı olabilirim. Projeni konuşmak için iletişime geç.

Bu kategorideki tüm yazılar →

Devamı için