# N+1 Sorgu Sorunu

Adres: https://softwaredictionary.org/tr/terimler/n-plus-one-query
Kategori: Veritabanları
Son güncelleme: 2026-09-30
İngilizcesi: N+1 Query Problem
Okunuşu: en plas van kuiri problım

Kısaca: N+1 sorgu sorunu, kodun bir listeyi tek sorguyla yükleyip sonra her öğe için bir sorgu daha çalıştırdığı, hepsini birden getirmediği bir performans hatasıdır.

## N+1 sorgu sorunu nedir?

N+1 sorgu sorunu, kod N kayıttan oluşan bir listeyi tek bir sorguyla getirip ardından üzerlerinde dolaşarak her kaydın ilişkili verisi için ayrı bir sorgu çalıştırdığında ortaya çıkar. Bu toplamda 1 + N sorgu eder. 10 kayıtla neredeyse fark edilmez, ancak 1.000 kayıtla tek bir sayfa yüklemesi veritabanına 1.001 sorgu gönderir.

Sorun çoğu zaman bir ORM'in lazy loading'i tarafından gizlenir: bir döngü içinde `post.author` okumak basit bir özellik erişimi gibi görünür, ancak her seferinde sessizce bir sorgu çalıştırır. Her sorgu tek başına küçük ve hızlıdır, ancak ağ gidiş-dönüşleri ve sorgu başına ek yük birleşince yavaş bir sayfa ortaya çıkar. Çözüm, ilişkili veriyi sabit ve az sayıda sorguyla getirmektir: ORM'de eager loading, tek bir `JOIN` ya da `WHERE id IN (...)` ile tek bir toplu sorgu kullanarak. GraphQL sunucuları bunu genellikle ID'leri toplayıp birlikte yükleyen, çoğu zaman data loader denen bir toplu işleme katmanıyla çözer.

Bu, alışveriş listenizdeki her ürün için markete bir kez gitmeye, hepsini tek seferde almak yerine, benzer. Sorunu veritabanı sorgu günlüklerinde, ORM hata ayıklama çıktısında ya da istek başına düzinelerce kez tekrarlanan aynı sorgu biçimini gösteren istek izlerinde (trace) fark edebilirsiniz; bazı ekipler bir endpoint belirli bir sorgu sayısını aştığında başarısız olan testler de ekler.

N+1 sorunu yavaş bir sorgudan farklıdır. Yavaş sorgu, bir indeks ya da yeniden yazımla çoğu zaman düzeltilebilen tek bir pahalı ifadedir; N+1 ise her biri kendi başına iyi görünen çok sayıda ucuz ifadedir, bu yüzden indeks eklemek yardımcı olmaz. Her şeyi eager loading ile yüklemek de her zaman cevap değildir; çünkü bir sayfanın hiç kullanmadığı ilişkili veriyi yüklemek bellek ve zaman israfıdır.

## Önemli noktalar

- N+1, bir liste için bir sorgu artı listedeki her öğe için bir sorgu demektir.
- ORM lazy loading'i en yaygın gizli nedendir.
- Her sorgu hızlıdır, ancak liste büyüdükçe gidiş-dönüşler birikir.
- Eager loading, bir `JOIN` ya da toplu bir `IN` sorgusuyla düzeltin.
- İndeksler N+1'i çözmez; çünkü sorun sorgu sayısıdır.

## Örnek: N+1 sorgular ve toplu bir çözüm

```javascript
// N+1: 1 query for the posts, then 1 query per post for its author
const posts = await db.query("SELECT * FROM posts LIMIT 50");
for (const post of posts) {
  const rows = await db.query("SELECT * FROM users WHERE id = ?", [post.author_id]);
  post.author = rows[0];
}

// Fix: load all the authors in one extra query (2 queries in total)
const ids = posts.map((p) => p.author_id);
const authors = await db.query("SELECT * FROM users WHERE id IN (?)", [ids]);
const byId = new Map(authors.map((a) => [a.id, a]));
for (const post of posts) post.author = byId.get(post.author_id);
```

## Sık sorulan sorular

**N+1 sorguları nasıl tespit ederim?**

ORM'inizde ya da veritabanında sorgu günlüğünü açın ve tek bir istek sırasında farklı ID'lerle tekrarlanan aynı sorguyu arayın. İzleme ve performans takip araçları ile bazı ORM eklentileri örüntüyü otomatik olarak işaretleyebilir.

**ORM kullanmak N+1 sorununa yol açar mı?**

ORM tek başına buna yol açmaz, ancak lazy loading bunu yanlışlıkla yazmayı çok kolaylaştırır. Çoğu ORM, ilişkili kayıtları baştan yüklemek için `include` ya da `prefetch` gibi eager loading seçenekleri sunar.

**JOIN her zaman N+1 sorgulardan daha mı iyidir?**

Genellikle, ama her zaman değil. Bir birleştirme üst veriyi birçok satır boyunca çoğaltabilir; bu yüzden büyük bire-çok ilişkilerde biri üst kayıtlar, diğeri alt kayıtlar için toplu iki sorgu çoğu zaman daha temiz ve aynı derecede hızlıdır.

---

Software Dictionary: https://softwaredictionary.org/tr · https://softwaredictionary.org/tr/llms.txt
