⚙️ MongoDB İndeks Kullanımı: Koleksiyon Sorgularını Hızlandırma Rehberi
🚀 Bu Rehberde Ne Öğreneceksiniz?
Bu rehber, MongoDB veritabanında indekslerin (index/dizin) nasıl çalıştığını, neden önemli olduğunu ve sorgu performansını nasıl hızlandırdığını öğretir.
Tekil, benzersiz, gömülü (nested) ve bileşik (compound) indekslerin nasıl oluşturulacağını; ayrıca explain() metodu ile indekslerin sorgu planında nasıl kullanıldığını adım adım öğreneceksiniz.
🧠 Teknik Özet
Konu: MongoDB’de indekslerin oluşturulması ve sorgu performansını artırma teknikleri.
Amaç: Koleksiyon büyüdükçe sorguların yavaşlamasını engellemek; tam tarama (Collection Scan) yerine indeks taraması (Index Scan) kullanmak.
Adımlar:
- Örnek veritabanı ve koleksiyon oluşturma
- İndekssiz sorgu planını inceleme
- Tek alanlı indeks oluşturma
- Benzersiz (unique) indeks ekleme
- Gömülü alanlara (nested) indeks uygulama
- Bileşik (compound) indeks oluşturma
- İndeksleri listeleme ve silme
📦 1. Adım – Örnek Veritabanını Hazırlama
İlk olarak MongoDB kabuğuna yönetici hesabınızla bağlanın:
mongo -u rabisu_admin -p --authenticationDatabase admin
➡️ MongoDB’ye kimlik doğrulamalı giriş yapar.
Şimdi zirveler adlı bir koleksiyon oluşturun ve örnek verileri ekleyin:
db.zirveler.insertMany([
{
"isim": "Everest",
"yukseklik": 8848,
"lokasyon": ["Nepal", "Çin"],
"tirmanislar": { "ilk": { "yil": 1953 }, "toplam": 5656 }
},
{
"isim": "K2",
"yukseklik": 8611,
"lokasyon": ["Pakistan", "Çin"],
"tirmanislar": { "ilk": { "yil": 1954 }, "toplam": 306 }
},
{
"isim": "Lhotse",
"yukseklik": 8516,
"lokasyon": ["Nepal", "Çin"],
"tirmanislar": { "ilk": { "yil": 1956 }, "toplam": 461 }
},
{
"isim": "Makalu",
"yukseklik": 8485,
"lokasyon": ["Çin", "Nepal"],
"tirmanislar": { "ilk": { "yil": 1955 }, "toplam": 361 }
}
])
➡️ Beş dağ zirvesi için örnek belgeleri ekler.
Kayıtları görüntülemek için:
db.zirveler.find()
⚡ 2. Adım – İndekssiz Sorgu Performansını Analiz Etmek
8700 metreden yüksek zirveleri sorgulayın:
db.zirveler.find({ "yukseklik": { $gt: 8700 } }).explain("executionStats")
➡️ Sorgunun nasıl yürütüldüğünü gösterir.
winningPlan.stage: "COLLSCAN" ifadesi, MongoDB’nin tüm koleksiyonu taradığını gösterir. totalDocsExamined: 5 ise her belgenin kontrol edildiğini belirtir.
🔍 3. Adım – Tek Alanlı İndeks Oluşturma
yukseklik alanına bir indeks ekleyelim:
db.zirveler.createIndex({ "yukseklik": 1 })
➡️ Artan (ascending) düzende indeks oluşturur.
Aynı sorguyu tekrar çalıştırın:
db.zirveler.find({ "yukseklik": { $gt: 8700 } }).explain("executionStats")
Bu kez IXSCAN görünecek ve totalDocsExamined 5’ten 1’e düşecektir. Artık MongoDB yalnızca eşleşen belgeleri okur — tam tarama yok.
🔐 4. Adım – Benzersiz (Unique) İndeks Oluşturma
Aynı isimde iki belge olmasını önlemek için unique indeks kullanılır:
db.zirveler.createIndex({ "isim": 1 }, { "unique": true })
➡️ İsim alanında tekrar eden değerlere izin vermez.
Aşağıdaki sorgu artık hata döndürür:
db.zirveler.insertOne({ "isim": "Everest", "yukseklik": 9000 })
Hata: E11000 duplicate key error collection: zirveler index: isim_1
🧩 5. Adım – Gömülü (Nested) Alanlara İndeks Eklemek
Belge içindeki gömülü alanlara da indeks eklenebilir. Örneğin tirmanislar.toplam alanı:
db.zirveler.createIndex({ "tirmanislar.toplam": 1 })
➡️ Gömülü belgedeki toplam alanına indeks ekler.
Sorgu artık daha hızlı çalışacaktır:
db.zirveler.find(
{ "tirmanislar.toplam": { $gt: 300 } }
).sort({ "tirmanislar.toplam": -1 }).explain("executionStats")
Sonuçta "stage": "IXSCAN" görünür — MongoDB artık indeksi kullanır.
🧱 6. Adım – Bileşik (Compound) İndeksler
Birden fazla alana göre sorgulama yapıyorsanız bileşik indeksler idealdir:
db.zirveler.createIndex(
{ "tirmanislar.ilk.yil": 1, "yukseklik": -1 }
)
➡️ İlk tırmanış yılı artan, yükseklik azalan sıralamada indeks oluşturur.
Bileşik indeksler, en soldaki alandan başlayarak (leftmost prefix) sorgularda etkili olur. Yani önce tirmanislar.ilk.yil, sonra yukseklik alanı üzerinden çalışır.
🌍 7. Adım – Çok Değerli (Multi-key) Alanlara İndeks Eklemek
Bir alan birden fazla değere sahipse (örneğin dizi içeren lokasyon alanı), MongoDB otomatik olarak multi-key indeks oluşturur.
db.zirveler.createIndex({ "lokasyon": 1 })
➡️ Her ülke değeri için ayrı indeks kaydı tutar.
Sorgu örneği:
db.zirveler.find({ "lokasyon": "Nepal" }).explain("executionStats")
Çıktıda "isMultiKey": true ifadesi yer alacaktır.
🗂️ 8. Adım – İndeksleri Listeleme ve Kaldırma
Tüm indeksleri listelemek için:
db.zirveler.getIndexes()
➡️ Tanımlı tüm indeksleri gösterir.
Belirli bir indeksi silmek için:
db.zirveler.dropIndex("yukseklik_1")
Tüm indeksleri temizlemek için:
db.zirveler.dropIndexes()
💬 Sıkça Sorulan Sorular (SSS)
- Çok fazla indeks performansı düşürür mü?
Evet. Her ekleme/güncellemede indeksler yeniden hesaplanır. Gereksiz indeksler yazma işlemlerini yavaşlatır.
- explain() metodunda hangi değerler önemlidir?
winningPlan.stage: COLLSCAN (koleksiyon taraması) veya IXSCAN (indeks taraması).
totalDocsExamined: Kaç belgenin incelendiği.
nReturned: Kaç belgenin döndüğü.
- İndeksleri düzenleyebilir miyim?
Hayır, mevcut indeksi silebilir (dropIndex) ve yeniden oluşturabilirsiniz.
- Arka planda indeks oluşturmak mümkün mü?
Evet, büyük koleksiyonlarda sistemin kitlenmemesi için şu şekilde:
db.zirveler.createIndex({ "alan": 1 }, { background: true })
- Hangi alanlara indeks eklemeliyim?
Sık sorgulanan, filtre veya sıralama (sort) yapılan alanlara indeks ekleyin.
🎯 Sonuç
Bu rehberde, MongoDB’de indekslerin sorgu performansına etkisini öğrendiniz. Artık tekil, benzersiz, gömülü ve bileşik indeksleri nasıl oluşturacağınızı biliyorsunuz. Doğru indeksleme, büyük veri setlerinde performans farkı yaratır.