Entity Framework Core: N+1 Sorgu Problemini Çözmek

Entity Framework Core kullanırken sık karşılaşılan bir performans sorunu vardır: bir ana veriyi çekerken, her ilişkili veri için ayrı bir sorgu yapılması. Örneğin 10 yazarın kitaplarını listelemek için 1 sorgu yazarlar için, sonra 10 sorgu her yazar için kitapları çekmek anlamına gelir. Toplamda 11 sorgu. buna N+1 diyoruz.

Aşağıdaki modelleri düşün:

1public class Author
2{
3public int Id { get; set; }
4public string Name { get; set; }
5public ICollection<Book> Books { get; set; }
6}
7
8public class Book
9{
10public int Id { get; set; }
11public string Title { get; set; }
12public int AuthorId { get; set; }
13}

Yanlış Yaklaşım (N+1 Sorunu):

1var authors = _context.Authors.ToList();
2foreach (var author in authors)
3{
4var books = _context.Books.Where(b => b.AuthorId == author.Id).ToList();
5// Her döngüde ayrı sorgu!
6}

Bu kod 1 + N sorgu çalıştırır. 100 yazar varsa 101 sorgu!

İlişkili verileri önceden yükle:

Reklam · TEST
AdSense Test ReklamıYazı arası (gönderi içi) · Yazı arası
1var authors = _context.Authors.Include(a => a.Books).ToList();
2
3foreach (var author in authors)
4{
5Console.WriteLine($"{author.Name}: {author.Books.Count} kitap");
6}

Çıktı:

1Orhan Pamuk: 5 kitap
2Ahmet Ümit: 3 kitap

Artık 1 sorgu yeterli. SQL'de `LEFT JOIN` kullanılır.

Sadece ihtiyacın olan alanları çek:

1var result = _context.Authors.Select(a => new
2{
3a.Name,
4BookCount = a.Books.Count()
5}).ToList();
6
7foreach (var item in result)
8{
9Console.WriteLine($"{item.Name}: {item.BookCount} kitap");
10}
11[/cod]
12
13Bu yöntem veri tabanında `COUNT` işlemini yapar. Daha hızlıdır.
14
15Veriyi sadece okuyacaksan tracking'i kapat:
16
17[kod]
18var authors = _context.Authors.AsNoTracking().Include(a => a.Books).ToList();

Tracking kapalı olunca bellek kullanımı azalır.

N+1 sorgusu veritabanını gereksiz yere yükler. Include() ile ilişkili veriyi önceden yükle, Select() ile sadece gerekli alanları çek, AsNoTracking() ile bellek tasarrufu yap. Böylece 1 sorgu yeterli olur ve uygulamanın performansı artar.

Reklam · TEST
AdSense Test ReklamıGönderi altı · Görüntülü
konu hakkında tepkinizi verebilirsiniz