Veritabanı mühendisliği alanında, indeks oluşturmak genellikle yavaş sorgulara karşı ilk savunma hattıdır. Ancak, orta ve ileri düzey geliştiriciler için varsayılan "bu sütuna indeks oluştur" yaklaşımı, yüksek performanslı uygulamalar için nadiren yeterlidir. Karmaşık iş yüklerini gerçekten optimize etmek için, kapsayıcı, kısmi ve bileşik indeksler arasındaki nüanslı farkları anlamak gerekir. Bu yazı, bu desenleri stratejik olarak birleştirerek I/O'yu azaltmanın, depolama maliyetlerini düşürmenin ve sorgu yürütme hızını artırmanın yollarını inceler.
Bileşik İndekslerin Gücü
Bileşik indeks (çok sütunlu indeks olarak da bilinir), iki veya daha fazla sütun üzerinde oluşturulur. İndeks tanımındaki sütunların sırası kritiktir çünkü indeksin destekleyebileceği sorgu desenlerini belirler. Veritabanı indeksleri genellikle sıralı veri yapıları olan B-Ağaçları olarak uygulanır. Bu, veritabanının bir bileşik indeksi yalnızca sorgunun WHERE yan tümcesinde indeksin en soldaki sütunundan başlayarak verimli bir şekilde kullanabileceği anlamına gelir.
Sık sık `status` (durum) ile filtreleme yapıp ardından `created_at` (oluşturulma tarihi) ile sıralama yaptığınız bir senaryoyu düşünün. (status, created_at) üzerinde bir bileşik indeks oluşturursanız, veritabanı belirli durum değerlerini hızlıca bulabilir ve ayrı bir sıralama adımı olmadan sıralı bir şekilde getirebilir. Ancak, yalnızca `created_at` ile filtreleme yapan bir sorgu, `status` sütunu yüksek seçicilikte bir filtre görevi görmezse veya veritabanı indeks atla-tarama (index skip-scan) gibi bir özellik kullanmıyorsa, bu indeksi büyük ölçüde yok sayacaktır.
-- Verimli: Önce duruma göre filtreler, ardından tarihe göre sıralar
CREATE INDEX idx_order_status_date ON orders (status, created_at DESC);
-- Verimsiz: Tarihe göre tam tablo taraması için yukarıdaki indeksi etkili bir şekilde kullanmaz
SELECT * FROM orders WHERE created_at > '2023-01-01';
Seyrek Veriler İçin Kısmi İndekslerin Uygulanması
Kısmi indeksler, bir tablonun koşullu bir ifadeyle tanımlanan bir alt kümesi üzerinde oluşturulan indekslerdir. Belirli kriterleri karşılayan satırların küçük bir yüzdesini sık sık sorguladığınızda özellikle faydalıdırlar. Yalnızca bu satırları indeksleyerek indeksin boyutunu önemli ölçüde küçültürsünüz; bu da önbellek verimliliğini artırır ve hem okuma hem de yazma işlemlerini hızlandırır.
Örneğin, bir e-ticaret platformunda siparişlerin çoğu 'tamamlandı' olabilir, ancak müşteri hizmetleri temsilcileri sık sık 'beklemede' veya 'başarısız' siparişleri sorgular. Bu sorgular için tüm tabloyu indekslemek israftır. Kısmi indeks, kaynaklarınızı aktif ve sorunlu kayıtlara odaklamanızı sağlar.
-- Yalnızca durumu beklemede olan satırları indeksleyin
CREATE INDEX idx_pending_orders ON orders (customer_id, total)
WHERE status = 'pending';
Bu yaklaşım, indeksi yalnızca daha küçük ve gezinmesi daha hızlı yapmakla kalmaz, aynı zamanda INSERT ve UPDATE işlemleri sırasında da aşırı yükü azaltır; çünkü veritabanı verilerin büyük çoğunluğu için indeks girişlerini korumak zorunda kalmaz.
Aramaları Ortadan Kaldırmak İçin Kapsayıcı İndeksler
Bir kapsayıcı indeks, bir sorgu tarafından gereken tüm sütunları içeren bir indekstir. Bu, veritabanı motorunun sorguyu yalnızca indeks yapısını okuyarak karşılayabileceği ve asıl satır verilerini yığın (ana tablo deposu) içinden getirmek için pahalı rastgele I/O işlemleri gerçekleştirmeye gerek kalmayacağı anlamına gelir. Buna "sadece indeks taraması" (index-only scan) denir.
Kapsayıcı indeksler okuma performansını dramatik şekilde artırabilse de, bunun karşılığında bazı fedakarlıklar gerektirir. Daha fazla disk alanı tüketirler ve indeks yapısında daha fazla veri korunması gerektiğinden yazma işlemlerinin (INSERT, UPDATE, DELETE) maliyetini artırır. Bu nedenle, yalnızca en kritik ve sık kullanılan sorgularınız için seçici olarak kullanılmalıdırlar.
-- Bu sorgu tüm sütunlar indekste olduğu için indeks-only tarama gerçekleştirir
CREATE INDEX idx_order_coverage ON orders (order_id, customer_id, total);
SELECT customer_id, total
FROM orders
WHERE order_id = 12345;
Stratejik Uygulama
İndeksleme stratejinizi tasarlarken, EXPLAIN ANALYZE gibi araçları kullanarak en yavaş sorgularınızı analiz etmeye başlayın. Sıralama ve filtrelemeyi optimize etmek için bileşik indeksleme uygulayabileceğiniz desenleri belirleyin. Aşırı yükü azaltmak için kısmi indekslemeden faydalanabilecek seyrek veri alt kümelerini arayın. Son olarak, yığın aramalarını ortadan kaldırmak için kapsayıcı indekslerden faydalanabilecek yüksek frekanslı okuma sorgularını belirleyin.
İndekslemenin bir dengeleme oyunu olduğunu unutmayın. Daha fazla indeks, daha hızlı okumalar ama daha yavaş yazmalar ve daha yüksek depolama maliyetleri anlamına gelir. Veritabanı performansınızı her zaman izleyin ve uygulamanızın sorgu desenleri değiştikçe indeksleme stratejinizi ayarlayın.
Sonuç
Gelişmiş indeksleme desenlerine hakim olmak, ölçeklenebilir ve yüksek performanslı sistemler oluşturmaya hedefleyen veritabanı mühendisleri için esastır. Çok sütunlu filtreleme için bileşik indeksleri, seyrek veri kümeleri için kısmi indeksleri ve I/O'yu en aza indirmek için kapsayıcı indeksleri kullanarak, hantal veritabanlarını hızlı ve verimli varlıklara dönüştürebilirsiniz. Bu teknikleri yerinde uygulayın ve kararlarınızı her zaman ampirik sorgu analizine dayandırın.