Entity Framework Core, ASP.NET Core ekosisteminde veri erişimini büyük ölçüde kolaylaştırıyor, ama bu kolaylık dikkatsiz kullanıldığında ciddi performans sorunlarına yol açabiliyor. Bu yazıda, projelerimde en sık karşılaştığım ve çözdüğüm EF Core performans sorunlarını paylaşıyorum.
N+1 Sorgu Problemi
En sık gördüğüm hata, bir listeyi döngüyle gezerken her elemanın ilişkili verisini ayrı ayrı sorgulamak. Include() ile ilişkili veriyi tek sorguda çekmek, yüzlerce küçük sorgu yerine tek bir join sorgusu çalıştırılmasını sağlıyor.
var orders = await _context.Orders
.Include(o => o.Customer)
.Include(o => o.Items)
.ToListAsync();
AsNoTracking Kullanmayı Unutmamak
Sadece okuma amaçlı sorgularda EF Core'un değişiklik takibi (change tracking) mekanizmasına ihtiyacım yok. AsNoTracking() eklemek, hem bellek kullanımını azaltıyor hem de sorgu performansını gözle görülür şekilde artırıyor. Salt okunur API endpoint'lerinin neredeyse tamamında bunu varsayılan hale getirdim.
Projeksiyon Kullanmak, Tüm Entity'yi Çekmemek
Bir listede sadece iki alana ihtiyacım varsa, tüm entity'yi çekip sonra mapping yapmak yerine doğrudan Select() ile projeksiyon yapıyorum. Bu, hem transfer edilen veri miktarını azaltıyor hem de veritabanının gereksiz kolonları okumasını engelliyor.
Sayfalama Olmadan Büyük Listeleri Çekmemek
"Şimdilik az kayıt var" diyerek sayfalamasız bir sorgu yazmak, veri büyüdükçe uygulamayı yavaşlatan sinsi bir hataya dönüşüyor. Her liste endpoint'inde Skip()/Take() ile sayfalamayı baştan zorunlu tutuyorum.
Migration'ları Kontrollü Yönetmek
EF Core migration'larını üretim ortamında otomatik uygulamak yerine, bir CI/CD adımında kontrollü şekilde çalıştırıyorum. Bu, beklenmedik bir şema değişikliğinin canlı ortamda sürpriz yapmasını engelliyor.
Sonuç
EF Core'un sağladığı kolaylık, doğru kullanıldığında geliştirme hızını gerçekten artırıyor. Ama her ORM gibi, "sihirli" gördüğümüz noktalarda neler olup bittiğini anlamadan ilerlemek, projeyi büyüdükçe yavaşlatan gizli maliyetlere dönüşüyor.