TEMEL
Index Yapılandırması
Index, sorgu performansını doğrudan etkiler. WHERE, ORDER BY veya JOIN sık kullandığın sütunlara index koymak sorguyu tablonun tamamını taramaktan kurtarır.
Veritabanı sağlayıcısı
Bu sayfadaki eşleşen örnekleri seçilen sağlayıcıya göre gösterir.
Fluent API
// Tek kolon index
builder.HasIndex(p => p.Email);
// Unique index
builder.HasIndex(p => p.Email).IsUnique();
// Bileşik index
builder.HasIndex(p => new { p.LastName, p.FirstName });
// Kümeleli (Clustered) index — SQL Server
builder.HasIndex(p => p.CreatedAt).IsClustered();
// Non-clustered unique — SQL Server
builder.HasKey(p => p.Id).IsClustered(false);
// Index adı
builder.HasIndex(p => p.Email).HasDatabaseName("IX_Users_Email");
// Filtrelenmiş index (partial index)
builder.HasIndex(p => p.Email)
.IsUnique()
.HasFilter("[DeletedAt] IS NULL");
// Include columns (SQL Server — covering index)
builder.HasIndex(p => p.LastName)
.IncludeProperties(p => new { p.FirstName, p.Email });
// Index yorum
builder.HasIndex(p => p.Sku)
.HasDatabaseName("IX_Products_Sku")
.HasComment("Stok kodu için benzersiz index");
SQL Karşılıkları:
-- Tek kolon index
CREATE NONCLUSTERED INDEX [IX_Users_Email]
ON [Users] ([Email]);
-- Unique index
CREATE UNIQUE NONCLUSTERED INDEX [IX_Users_Email]
ON [Users] ([Email]);
-- Bileşik index
CREATE NONCLUSTERED INDEX [IX_Users_LastName_FirstName]
ON [Users] ([LastName], [FirstName]);
-- Filtrelenmiş index (soft delete senaryosu)
CREATE UNIQUE NONCLUSTERED INDEX [IX_Users_Email]
ON [Users] ([Email])
WHERE [DeletedAt] IS NULL;
-- Covering index (Include)
CREATE NONCLUSTERED INDEX [IX_Users_LastName]
ON [Users] ([LastName])
INCLUDE ([FirstName], [Email]);
-- Tek kolon index (btree varsayılan)
CREATE INDEX ix_users_email ON users (email);
-- Unique index
CREATE UNIQUE INDEX ix_users_email ON users (email);
-- Bileşik index
CREATE INDEX ix_users_lastname_firstname ON users (last_name, first_name);
-- Partial index (filtered — soft delete)
CREATE UNIQUE INDEX ix_users_email ON users (email) WHERE deleted_at IS NULL;
-- Covering index (PG 11+)
CREATE INDEX ix_users_lastname ON users (last_name) INCLUDE (first_name, email);
-- PostgreSQL'e özgü index türleri:
CREATE INDEX ix_products_tags ON products USING gin (tags); -- GIN: Array/JSONB/FTS
CREATE INDEX ix_products_search ON products USING gin (search_vector); -- Full-text
CREATE INDEX ix_products_location ON products USING gist (location); -- GiST: Spatial
CREATE INDEX ix_products_created ON products USING brin (created_at); -- BRIN: Büyük tablo, sıralı veri
// PostgreSQL'e özgü index türleri (Fluent API)
builder.HasIndex(p => p.Tags)
.HasMethod("gin"); // GIN: Array, JSONB, Full-text için
builder.HasIndex(p => p.SearchVector)
.HasMethod("gin"); // Full-text search vector
builder.HasIndex(p => p.Location)
.HasMethod("gist"); // GiST: Geometric/range types için
builder.HasIndex(p => p.CreatedAt)
.HasMethod("brin"); // BRIN: Büyük tablolarda tarih/sıralı veri (çok küçük index)
// Partial index (filtrelenmiş) — PostgreSQL syntax:
builder.HasIndex(p => p.Email)
.IsUnique()
.HasFilter("deleted_at IS NULL"); // Köşeli parantez yok (PG syntax)
// Collation-aware index (case-insensitive aramalar için)
builder.HasIndex(p => p.Email)
.UseCollation("und-x-icu"); // ICU collation
PostgreSQL index seçim rehberi:
| Index Metodu | Ne Zaman | Boyut | Performans |
|---|---|---|---|
btree |
Eşitlik + sıralama (varsayılan) | Orta | Genel amaç |
hash |
Sadece eşitlik (=) |
Küçük | Hızlı ama kısıtlı |
gin |
Array @>, JSONB, Full-text @@ |
Büyük | Çok değerli aramalar |
gist |
Range, geometric, nearest-neighbor | Orta | Spatial/Range |
brin |
Büyük tabloda sıralı kolon (tarih) | Çok küçük | Yaklaşık |
Index Limitleri (PostgreSQL):
Limit Değer Max sütun/index (btree) 32 Max index boyutu (satır) 2.712 byte Max index/tablo Sınır yok (pratik: <50) Max index adı 63 karakter Pratik öneriler:
- Kullanılmayan index'leri tespit et:
pg_stat_user_indexes→idx_scan = 0olanları kaldır- GIN index büyük olabilir (tablo boyutunun 2-3 katı) — sadece gerçekten gerektiğinde ekle
Index ne zaman gerekir?
| Durum | Index Tipi |
|---|---|
WHERE Email = ? sorgularında |
Tek kolon index |
| Benzersiz olması gereken alan | Unique index |
WHERE LastName = ? AND FirstName = ? |
Bileşik index |
| Soft delete + unique | Filtered / Partial index |
| SELECT'te FK join sonrası extra sütun lazım | Covering index (INCLUDE) |
| Array/JSONB içinde arama | GIN index (PostgreSQL) |
| Büyük tabloda tarih filtresi | BRIN index (PostgreSQL) |
Index Limitleri (SQL Server):
Limit Değer Max sütun/index 16 (include hariç) Max index boyutu (satır) 1.700 byte Max index/tablo Sınır yok (pratik: <50) Max index adı 128 karakter