COMPUTER ENGINEER

Örneklere git
Blog
Next.js / ASP.NET Core / SQL6 dk çalışma
28/ 41

Veri katmanı ve SQL

N+1 problemi, Include ve AsNoTracking

Döngü içinde sorgu atmanın gizli maliyeti ve okuma sorgularını hafifletmek.

AnlaÖrneği inceleKendin uygula

Kavramı anlayalım

N+1 problemi, bir liste için bir sorgu atıp ardından listedeki her öğe için ayrı bir sorgu daha atmaktır. 20 yazı listelenirken her yazının yazarı ayrı yüklenirse 1 + 20 = 21 sorgu çalışır. Her sorgu tek başına hızlı görünür; ama ağ gidiş-dönüşleri toplandığında sayfa yavaşlar ve veri büyüdükçe sorun katlanır. Geliştirme ortamında az veriyle fark edilmez, üretimde ortaya çıkar.

Çözüm, ilişkili veriyi aynı sorguda getirmektir. Include, navigasyon özelliğini JOIN ile yükler. Okuma için daha iyi yol çoğunlukla projeksiyondur: Select içinde p.Author.Name kullanmak, EF Core’un yalnız gerekli kolonlarla bir JOIN üretmesini sağlar.

Varsayılan olarak EF Core yüklediği entity’leri değişiklik için izler. Yalnız okunacak veride bu boşa harcanan bellek ve işlemcidir. AsNoTracking izlemeyi kapatır; okuma uç noktalarında daha hızlı ve hafiftir. Simülatördeki ‘Yavaş liste: N+1’ senaryosu farkı süre çizelgesinde gösterir.

NERESİNDE KULLANIRSIN?

N+1, üretimdeki en yaygın ORM performans sorunudur ve kodu okuyarak kolayca gözden kaçar.

SIK YAPILAN HATA

Lazy loading’i açıp navigasyon özelliklerine döngü içinde erişmek.

CANLI ANİMASYON

Bir mektubun şehirdeki yolculuğu

İsteği bir mektup, sunucuyu bir şehir gibi düşün. Senaryo seç, oynat ve mektubun hangi kapıdan geçip nerede durdurulduğunu izle.

İSTEMCİKENARWEB SUNUCUSUAPI · ASP.NET COREVERİTarayıcıKullanıcının ekranıAğDNS · TCP · TLSTers vekilTLS sonlandırma, sıkıştırmaNext.js sunucusuSSR ve route handlerKestrelHTTP sunucusuHata yakalayıcıMiddlewareRoutingEndpoint seçimiHız sınırıMiddlewareKimlik doğrulamaKim olduğunYetkilendirmeNeye izin varModel bindingHTTP → C# + doğrulamaControllerEndpoint koduServisİş kuralları (DI)RedisDağıtık önbellekEF CoreLINQ → SQLSQL ServerSorgu planı, indeks
GİDİŞ →

Blog sayfası 20 yazıyı yazar adlarıyla birlikte istiyor.

TarayıcıSenin ekranın. İsteği yazan ve sonunda cevabı sayfaya çeviren yer.
1 / 8
01 / UYGULAMA

Aynı konu. Üç farklı derinlik.

Temsili örnek
// ✗ N+1
var posts = await db.Posts.Take(20).ToListAsync(ct);
foreach (var p in posts)
    p.AuthorName = (await db.Authors.FindAsync(p.AuthorId))!.Name; // 20 ek sorgu

Döngü içindeki her await bir veritabanı gidiş-dönüşüdür.

Bu sayfa gerçek bir sunucuya veya veritabanına bağlanmaz. Kod örnekleri .NET 8, Next.js ve SQL Server için temsilîdir; süreler simülasyondaki örnek değerlerdir, ölçüm değildir. Örnekleri yalnız kendi geliştirme ortamında dene; gerçek bağlantı dizesi, token veya parola paylaşma.

02 / SIRA SENDE

Önce kendin dene.

Bir sipariş sayfası her siparişin müşterisini ve her siparişin ürünlerini gösteriyor. 50 sipariş için SQL günlüğünde 101 sorgu var. Hangi iki ilişki N+1 üretiyor ve tek sorguya nasıl indirirsin?

Çözümü ve açıklamasını göster
Açıklamalı çözüm
1 (siparişler) + 50 (müşteri) + 50 (ürünler) = 101
Düzeltme: projeksiyon
db.Orders.AsNoTracking().Select(o => new OrderView(
    o.Id, o.Customer.Name,
    o.Items.Select(i => i.Product.Name).ToList()))
// koleksiyon için AsSplitQuery() de değerlendirilebilir

Her ilişki için döngüde yükleme N sorgu ekler. Projeksiyon ilişkileri JOIN’e çevirir; büyük koleksiyonlarda bölünmüş sorgu kartezyen patlamayı önler.