---
title: "İndeks Yönetimi: Eksik Yavaşlatır, Fazlası Yazmayı Öldürür"
description: "Eksik indeks sorguyu yavaşlatır, gereğinden fazla indeks her yazma işlemini pahalılaştırır. Doğru dengeyi tahminle değil ölçümle kurmak."
url: https://sade.dev/tr/notes/indeks-yonetimi/
lang: tr
author: "Muhammet Şafak"
published: 2026-09-05
section: Note
tags: ["postgresql","database","performance","indexing"]
---

# İndeks Yönetimi: Eksik Yavaşlatır, Fazlası Yazmayı Öldürür

> Eksik indeks sorguyu yavaşlatır, gereğinden fazla indeks her yazma işlemini pahalılaştırır. Doğru dengeyi tahminle değil ölçümle kurmak.

İki karşıt ekip gördüm. Biri tabloya hiç indeks koymamıştı — her sorgu bir sequential scan, her liste sayfası saniyeler sürüyordu. Diğeri tam tersini yapmıştı: "ne olur ne olmaz" diye her kolona bir indeks açmıştı ve şimdi her `INSERT` ağır aksak ilerliyordu.

İkisi de aynı yanılgının iki ucu: indeksi ücretsiz bir hız kaynağı sanmak.

## İndeks ücretsiz hız değildir

Bir indeks okumayı hızlandırır, çünkü veritabanı tüm tabloyu taramak yerine sıralı bir yapıya bakar. Ama o sıralı yapı kendi kendine güncel kalmaz: tablodaki bir `INSERT`, o tablonun **her indeksine** bir girdi yazar; bir `UPDATE` de indeksli bir kolona dokunduğu anda aynısını yapar. İstisnalar var — indeksli hiçbir kolonu değiştirmeyen HOT güncellemesi indekslere dokunmaz, kısmi indeks yüklemi dışında kalan satırlar için güncellenmez, `DELETE` ise indeks girdilerini temizlemeyi `VACUUM`'a bırakır — ama bunlar istisna, varsayılan değil.

Yani her indeks bir takastır: okuma hızını, yazma maliyetiyle satın alırsınız. Beş indeksli bir tabloya tek satır eklemek, altı yapıyı birden güncellemektir. İndeks "bedava okuma hızı" değil, "yazmayla ödenmiş okuma hızı"dır.

## Eksik indeks: tahmin değil, ölçüm

Eksik indeksi sorgu planından bulun, tahminden değil:

```sql
EXPLAIN ANALYZE
SELECT * FROM orders WHERE status = 'pending';
```

Çıktıda büyük bir tabloda `Seq Scan` görüyorsanız ve sorgu satırların küçük bir kısmını döndürüyorsa, muhtemelen bir indeks eksiktir. `pg_stat_user_tables` tablosunda `seq_scan` sayısı yüksek olan büyük tabloları tarayın — bunlar adaylarınızdır.

İndeksi gerçek, yavaş bir sorgu için ekleyin. "İleride lazım olabilir" diye eklenen indeks, [spekülatif genelliğin](/tr/journal/ileride-lazim-olur-kodunun-faturasi) veritabanı katmanındaki hâlidir.

## Fazla indeks: kullanılmayanı bul

Ters yönde, hiç kullanılmayan indeksler her yazmayı boş yere pahalılaştırır. Onları da ölçümle bulun:

```sql
SELECT indexrelname, idx_scan
FROM pg_stat_user_indexes
WHERE idx_scan = 0;
```

`idx_scan = 0` olan bir indeks hiç okuma hızlandırmıyor ama her yazmaya maliyet ekliyor demektir. (Primary key ve unique kısıtların indekslerini elbette koruyun.) Bu, [veri yoğunluklu sistemlerin](/tr/systems/veri-yogunluklu-sistemler-kirilma-noktalari) yazma kırılma noktasında sayılan ilk temizliktir.

## Doğru indeksi seçmek

İndeks "var/yok"tan ibaret değildir; doğru türü ve şekli seçmek önemlidir:

- **Bileşik indekste kolon sırası.** `(a, b)` indeksi, `a`'da eşitlik + `b`'de aralık sorgusuna hizmet eder; `b`'de tek başına yapılan bir arama da bu indeksi kullanabilir ama taranan indeks bölümünü daraltmaz — PostgreSQL 18 öncesinde indeksin tamamı taranır, 18'den itibaren skip scan optimizasyonu bunu daraltır. Eşitlikle filtrelenen kolonu başa, aralıkla filtreleneni sona koyun.
- **Kısmi indeks (partial).** Sorgu hep aynı alt kümeye bakıyorsa indeksi de o alt kümeyle sınırlayın: `CREATE INDEX ... WHERE status = 'active'`. Daha küçük indeks, daha ucuz bakım.
- **Covering indeks.** `INCLUDE` ile sık okunan kolonları indekse ekleyip veritabanının tabloya hiç gitmemesini sağlayabilirsiniz.
- **B-tree dışı türler.** Eşitlik/sıralama için B-tree; `jsonb` ve tam metin için GIN; saf sıralı, append ağırlıklı veri için küçük ve ucuz BRIN.

## Duplikat ve örtüşen indeksler

`(a)` üzerindeki bir indeks, zaten `(a, b)` indeksiniz varsa gereksizdir — bileşik indeks `a` ile başlayan sorgulara da hizmet eder. Bu tür örtüşmeleri periyodik olarak temizleyin; her biri sessiz bir yazma vergisidir.

## Denge sorgu planıyla kurulur

Tek kural: indeksi ne tahminle ekleyin ne tahminle silin. Bir indeks, gerçek bir sorgu planı onu istediği için eklenir; bir indeks, istatistikler onu kimsenin kullanmadığını gösterdiği için silinir. Eksik ile fazla arasındaki denge, hislerle değil, `EXPLAIN ANALYZE` ve `pg_stat_user_indexes` ile kurulur.

---

İndeks yönetimi, "daha çok indeks daha iyi" sanısından kurtulmakla başlar. Her indeks bir okuma kazancı ve bir yazma maliyetidir; iyi yönetim, bu ikisini ölçerek dengede tutmaktır.

Eksik indeks sorguyu yavaşlatır; fazlası ise tüm tabloyu. İkisinden de ölçüm korur.
