ORM veritabanını gizlediğinde sorun başlar
ORM kullanmak üretkenliği artırır. Model sınıflarıyla çalışmak, migration üretmek ve ilişkileri koddan okumak geliştiriciyi hızlandırır. Sorun, ORM’in ürettiği SQL hiç görülmediğinde başlar.
Bir liste sayfası 50 kayıt getirirken her kayıt için ayrıca kullanıcı, ürün veya yorum sorgusu atıyorsa N+1 oluşur. Küçük veride fark edilmez; canlı ortamda kayıt sayısı büyüyünce veritabanı gereksiz sorgu altında ezilir.
- Geliştirme ortamında SQL logu belli senaryolarda açılmalıdır.
- Liste sayfaları sorgu sayısı ve toplam süreyle test edilmelidir.
- Lazy loading ve eager loading kararları bilinçli verilmelidir.
- ORM migration çıktısı indeks açısından gözden geçirilmelidir.
N+1 sorguyu sayarak yakalayın
N+1 sorunu çoğu zaman gözle değil logla anlaşılır. Aynı SELECT kalıbının küçük parametre farklarıyla tekrar tekrar çalıştığını görürsünüz. Çözüm bazen join, bazen batch loading, bazen de ayrı bir okuma modeli kurmaktır.
Ama her şeyi eager load etmek de çözüm değildir. Gereksiz eager loading, tek sorguda devasa veri döndürüp belleği ve ağı yorabilir.
N+1 kontrol notu
Sayfa / endpoint: Dönen kayıt sayısı: Toplam SQL sorgusu: Tekrarlayan sorgu kalıbı: Toplam veritabanı süresi: Çözüm adayı: join / batch load / read model / cache İndeks ihtiyacı:
Transaction içinde beklemeyin
ORM ile transaction açmak kolaydır; bu yüzden bazen fazla geniş kullanılır. Transaction içinde e-posta göndermek, dış API çağırmak, dosya işlemek veya kullanıcı cevabını beklemek kilitleri gereksiz yere uzun tutabilir.
İyi transaction kısa, net ve veritabanı işiyle sınırlıdır. Dış sistem çağrıları için outbox veya işlem sonrası asenkron akış daha sağlıklı olabilir.
Migration çıktılarını indeks gözüyle okuyun
ORM migration tabloyu ve foreign key’i oluşturabilir ama sorgularınızın ihtiyaç duyduğu composite indexleri otomatik bilmez. Özellikle tenant_id, status, created_at gibi birlikte filtrelenen kolonlar için indeks tasarımı kullanım desenine göre yapılmalıdır.
Canlıya çıkmadan önce en kritik listeleme, arama ve rapor sorgularının EXPLAIN çıktısı alınmalıdır. ORM kullanmak bu sorumluluğu ortadan kaldırmaz.
Sık listeleme için indeks fikri
create index concurrently idx_orders_tenant_status_created on orders (tenant_id, status, created_at desc);
PostgreSQL örneğidir. MySQL ve diğer motorlarda indeks oluşturma davranışı ayrıca değerlendirilmelidir.