VPS.TC
₺ | $
Sunucu Durumu
Turkey İstanbul, Türkiye
Aktif
USA New York, ABD
Aktif
Sepet Toplamı:
Sepeti Görüntüle
Veritabanı İndeksi Nedir? Sorgular Nasıl Hızlanır?
Teknoloji

Veritabanı İndeksi Nedir? Sorgular Nasıl Hızlanır?

Defne avatarı Defne 12 dk okuma 0 Yorumlar
Paylaş:

Hızlı Özet – Veritabanı İndeksi

İndeks, aranan satırlara daha az veri okuyarak ulaşmayı sağlayan yardımcı bir yapıdır. Doğru sorgu ve doğru kolon sırasıyla hız kazandırır; gereksiz kullanıldığında yazma işlemlerini ve disk tüketimini artırır.

  • Temel görev — İndeks, tabloyu baştan sona taramak yerine uygun kayda daha kısa yoldan ulaşır.
  • Ölçüm aracı — Sorgunun indeks kullanıp kullanmadığını ve tahmini maliyetini EXPLAIN çıktısıyla kontrol edin.
  • Kolon sırası — Birleşik indekslerde kolonların sırası, hangi sorguların verimli çalışacağını belirler.
  • Yazma maliyeti — INSERT, UPDATE ve DELETE işlemleri her ilgili indeksi de güncellediği için ek kaynak harcar.
  • Seçicilik — Çok az farklı değer içeren kolonlarda indeks, geniş tablo taramasından daha iyi olmayabilir.
  • Güvenli değişiklik — İndeksi staging ortamında test edin, üretim öncesi ve sonrası sorgu metriklerini karşılaştırın.

Veritabanı indeksi, tablodaki kayıtlara daha hızlı ulaşmak için kullanılan yardımcı veri yapısıdır. Kitap dizini gibi çalışarak veritabanının her satırı tek tek okumasını azaltır. Uygun indeks, özellikle büyük tablolarda sorgu süresini düşürür; yanlış indeks ise disk alanı tüketir, yazma işlemlerini yavaşlatır ve beklenen faydayı sağlamaz.

Veritabanı indeksi nedir ve ne işe yarar?

Veritabanı indeksi, tablodaki satırlara daha hızlı ulaşmak için oluşturulan yardımcı veri yapısıdır. Bir kitabın alfabetik dizini gibi çalışır; veritabanı her sorguda tablonun tamamını taramak yerine uygun indeksi kullanarak aranan kayıtlara daha kısa yoldan yaklaşabilir. Karşılığında disk alanı, ek yazma maliyeti ve bakım ihtiyacı getirir.

İndeks, verinin kendisi değildir. Tablodaki değerleri ve ilgili satır konumlarını düzenleyen ayrı bir yapıdır. MySQL 8.0 belgelerinde indekslerin özellikle WHERE, JOIN, ORDER BY ve bazı GROUP BY işlemlerinde sorgu maliyetini azaltabildiği belirtilir. Her kolona indeks eklemek doğru değildir; sorgunun yapısı, veri dağılımı ve tablonun yazma sıklığı birlikte değerlendirilmelidir.

🚀 VPS Sunucu ile Hızınızı Artırın!

Yüksek performanslı SSD depolama ve %99.9 uptime garantisi ile projelerinizi hızlandırın.

VPS Sunucu Kirala

Örneğin 10 milyon satırlık orders tablosunda customer_id alanı indekslenmemişse veritabanı aranan müşteriyi bulmak için çok sayıda satırı kontrol edebilir. Aynı alan üzerinde uygun bir indeks bulunduğunda arama alanı daralır. Bu hızlanmanın gerçek olup olmadığını tahminle değil, EXPLAIN çıktısıyla ölçmek gerekir.

Ne yapılmalı: İndeks eklemeden önce yavaş sorguyu EXPLAIN ile inceleyin ve sorgunun gerçekten tablo taraması yapıp yapmadığını doğrulayın.

Veritabanı sorguları indeks kullanarak nasıl hızlanır?

İndeksin çalışma mantığını basit bir arama üzerinden görmek kolaydır. İndeks yoksa veritabanı uygun kaydı bulmak için satırları baştan sona tarayabilir. Bu yönteme genellikle full table scan denir. Satır sayısı arttıkça okunacak veri miktarı da büyür.

☁️ Cloud Sunucu ile Esneklik Kazanın!

Ölçeklenebilir kaynaklar ve anlık yedekleme ile bulutun gücünü deneyimleyin.

Bulut Sunucu Paketleri

B-tree, ilişkisel veritabanlarında sık kullanılan indeks türlerinden biridir. Değerler dengeli bir ağaç yapısında tutulur. Arama, her satırı tek tek kontrol etmek yerine ağacın ilgili dalına ilerler. Bu yapı eşitlik aramalarında, aralık sorgularında ve sıralama işlemlerinde kullanılabilir.

Basitleştirilmiş sorgu:

SELECT id, email
FROM users
WHERE email = 'ayse@example.com';

users.email üzerinde uygun bir indeks varsa veritabanı e-posta değerini indeks üzerinden arayıp ilgili satıra geçebilir. İndeks yoksa tablo büyüklüğüne bağlı olarak daha fazla satır okunur. Hızlanma, işlemcinin sihirli biçimde daha hızlı çalışmasından değil, gereksiz disk ve bellek okumasının azalmasından gelir.

İndeksin etkisi VPS ortamında daha görünür olabilir. CPU kullanımı düşükken disk bekleme süresi yükseliyorsa sorgu gereğinden fazla veri okuyor olabilir. iostat, veritabanı slow query log’u ve EXPLAIN birlikte incelenmelidir.

İndeks neden her sorguyu hızlandırmaz?

Optimizasyon motoru her zaman indeksi seçmek zorunda değildir. Küçük bir tabloda tüm satırları okumak, indeks ağacını okuyup ardından tabloya gitmekten daha ucuz olabilir. Sorgu sonucunun tablonun büyük bölümünü döndürmesi de indeks avantajını azaltır.

Kolonun seçiciliği önemlidir. Milyonlarca satırda yalnızca iki farklı değer bulunan status alanı düşük seçiciliğe sahiptir. WHERE status = 'active' sorgusu satırların yüzde 90’ını döndürüyorsa geniş bir tarama daha verimli olabilir. Kesin karar gerçek veriler üzerindeki plan incelenerek verilmelidir.

Ne yapılmalı: İndeksin işe yaradığını yalnızca sorgu süresine bakarak değil, okunan satır sayısı ve seçilen erişim planıyla ölçün.

İpucu

Yavaş sorguyu kopyalayıp doğrudan üretimde değiştirmeden önce EXPLAIN ile planını kaydedin. İndeks ekledikten sonra aynı planı ve okunan satır sayısını yeniden karşılaştırın.

Bir tabloya indeks nasıl eklenir?

MySQL ve MariaDB’de tek kolonlu indeks oluşturmak için CREATE INDEX kullanılabilir:

CREATE INDEX idx_users_email
ON users (email);

Tabloyu değiştirerek de aynı işlem yapılabilir:

ALTER TABLE users
ADD INDEX idx_users_email (email);

İndeks adı yönetim açısından önemlidir. idx_users_email gibi bir ad, indeksin hangi tablo ve kolona ait olduğunu hemen gösterir. Üretim tablosunda işlem yapmadan önce tablo boyutunu, mevcut indeksleri ve olası kilitlenme etkisini kontrol edin. MySQL sürümüne ve depolama motoruna göre ALTER TABLE işleminin çevrimiçi çalışma davranışı değişebilir.

Mevcut indeksleri görmek için:

SHOW INDEX FROM users;

Çıktıdaki Key_name, Column_name, Non_unique ve Cardinality alanları özellikle değerlidir. Cardinality yaklaşık benzersiz değer sayısını gösterir; istatistiklere dayanır ve kesin satır sayısı anlamına gelmez.

PostgreSQL tarafında sözdizimi benzerdir:

CREATE INDEX idx_users_email
ON users (email);

PostgreSQL belgeleri indekslerin sorguları hızlandırırken ek depolama kullandığını ve veri değiştirme işlemlerine maliyet eklediğini belirtir. Kullanılmayan indeksleri periyodik olarak tespit etmek, yeni indeks eklemek kadar değerlidir.

Tek kolonlu ve birleşik indeks arasındaki fark nedir?

Tek kolonlu indeks yalnızca bir alanı kapsar. Birleşik indeks ise iki veya daha fazla kolonu belirli bir sırayla tutar:

CREATE INDEX idx_orders_customer_date
ON orders (customer_id, created_at);

Bu indeks aşağıdaki sorgu için genellikle anlamlıdır:

SELECT id, total
FROM orders
WHERE customer_id = 42
  AND created_at >= '2026-01-01'
ORDER BY created_at DESC;

Birleşik indekslerde kolon sırası kritik bir ayrıntıdır. (customer_id, created_at) sıralaması önce müşteriye, ardından tarihe göre daraltma yapar. Bu yapı yalnızca customer_id filtresi kullanan sorgulara da yardımcı olabilir. Sadece created_at ile arama yapan sorgu ise bu indeksi aynı verimle kullanamayabilir.

Bu davranış çoğu B-tree indeksinde soldan başlayan ön ek kuralıyla açıklanır. Üç kolonlu (a, b, c) indeksi için a veya a, b ile başlayan koşullar genellikle daha elverişlidir. Kolonların doğru sırası, en sık kullanılan sorgular ve filtrelerin seçiciliği incelenerek belirlenir.

İndeks Uygun sorgu örneği Dikkat edilmesi gereken
(customer_id) WHERE customer_id = 42 Tarih sıralamasını tek başına çözmez
(customer_id, created_at) Müşteri ve tarih filtresi Kolon sırası sorgu planını etkiler
(created_at, customer_id) Tarih aralığı öncelikli raporlar Müşteri bazlı aramalarda daha az uygun olabilir

Ne yapılmalı: Birleşik indeks kolonlarını tabloya göre değil, gerçek sorgu desenlerine göre ve soldan başlayan ön ek kuralını gözeterek sıralayın.

Örnek

10 milyon satırlık orders tablosunda müşteri ve tarih birlikte filtreleniyorsa (customer_id, created_at) indeksi uygun olabilir. Sadece created_at ile rapor alınıyorsa aynı indeksin yeterli olacağı varsayılmamalı, EXPLAIN çıktısı incelenmelidir.

EXPLAIN çıktısı nasıl okunur?

EXPLAIN, veritabanının bir sorguyu nasıl çalıştırmayı planladığını gösterir. MySQL için temel kullanım şöyledir:

EXPLAIN SELECT id, email
FROM users
WHERE email = 'ayse@example.com';

MySQL çıktısında type, possible_keys, key, rows ve Extra alanları ilk bakılacak yerlerdir. key seçilen indeksi gösterir. Boş olması her zaman hata değildir; fakat sorgunun milyonlarca satırı taradığı biliniyorsa araştırma gerekir.

  • type: Erişim yöntemini gösterir; const, eq_ref ve ref birçok arama için iyi işaretlerdir.
  • possible_keys: Kullanılabilecek indeksleri listeler.
  • key: Planlayıcının seçtiği indeksi gösterir.
  • rows: Okunması tahmin edilen satır sayısını verir.
  • Extra: Using filesort veya Using temporary gibi ek işlemleri gösterebilir.

MySQL 8.0 ile daha ayrıntılı analiz için EXPLAIN ANALYZE kullanılabilir:

EXPLAIN ANALYZE
SELECT id, total
FROM orders
WHERE customer_id = 42
ORDER BY created_at DESC
LIMIT 20;

Bu komut tahmini planın yanında gerçek çalışma süreleri ve gerçekleşen satır sayıları hakkında bilgi verir. Üretimde dikkatli kullanın; sorgu gerçekten çalıştırıldığı için büyük tablolar üzerinde ek yük oluşturabilir.

rows değerinin düşük olması tek başına yeterli değildir. Tahmin edilen ve gerçek satır sayıları arasında büyük fark varsa istatistikler güncel olmayabilir veya veri dağılımı planlayıcının varsayımını bozuyor olabilir.

Ne yapılmalı: İndeks değişikliğinden önce ve sonra aynı sorguyu aynı veri koşullarında EXPLAIN ile karşılaştırın.

Sahadan not

Üretimde bir indeks eklediğimde ALTER TABLE işlemi beklemede kaldı. SHOW PROCESSLIST çıktısında başka bir oturumın metadata lock tuttuğunu gördüm; işlemi durdurup değişikliği düşük trafikli pencereye taşıdım.

İndeks sorguyu ne zaman yavaşlatır?

Her indeksin bir bedeli vardır. Yeni satır eklendiğinde, indekslenen kolon değiştirildiğinde veya satır silindiğinde indeks yapısının da güncellenmesi gerekir. Çok sayıda indeks, yazma yoğun uygulamalarda ek disk yazımı ve daha fazla bellek tüketimi oluşturur.

İndeksler disk alanı da kullanır. Büyük VARCHAR, TEXT veya uzun ikili alanları doğrudan indekslemek pahalı olabilir. MySQL’de bazı metin alanlarında prefix index tercih edilebilir:

CREATE INDEX idx_articles_title_prefix
ON articles (title(100));

Buradaki 100, indekslenecek karakter ön ekinin uzunluğudur. Bu yaklaşım her sorguya uygun değildir; yalnızca ilk karakter dizisi yeterince ayırt ediciyse işe yarar. Unicode karakterlerde byte ve karakter uzunluklarının aynı olmayabileceğini de hesaba katın.

Gereksiz indeksler ayrı bir sorundur. Aynı kolonları aynı sırayla kapsayan iki indeks çoğunlukla fazladır. Örneğin (customer_id) ve (customer_id, created_at) birlikte bazı sorgular için gerekli olabilir; karar verilmeden önce sorgu kullanım sıklığı ve planlar incelenmelidir.

İndeks tanımları yedekleme boyutunu, tablo bakım sürelerini ve replikasyon trafiğini de etkileyebilir. VPS kaynakları sınırlıysa yalnızca sorgu hızına bakmak eksik bir değerlendirme olur.

Dikkat

Her kolona indeks eklemek performans ayarı değildir. İndeksler INSERT, UPDATE ve DELETE işlemlerinde güncellenir; fazla indeks yazma gecikmesini, disk kullanımını ve bakım süresini artırabilir.

LIKE, fonksiyonlar ve indeks kullanımı

Sorgunun yazılış biçimi, mevcut indeksin kullanılıp kullanılamayacağını belirler. Sağdan joker karakterle başlayan bir arama çoğu B-tree indeksinden yararlanamaz:

SELECT id, title
FROM articles
WHERE title LIKE '%linux%';

%linux% ifadesinde arama metninin başlangıcı bilinmediği için indeks ağacında belirli bir noktaya doğrudan gidilemez. Buna karşılık LIKE 'linux%' biçimi, uygun kolasyon ve veri tiplerinde indeks için daha elverişlidir.

Kolona fonksiyon uygulamak da indeks kullanımını engelleyebilir:

SELECT id
FROM users
WHERE LOWER(email) = 'ayse@example.com';

Bu sorgu için veritabanının normal email indeksini kullanması garanti değildir. Çözüm, uygulama tarafında değerleri normalize etmek, veritabanının desteklediği fonksiyonel indeksleri kullanmak veya uygun bir generated column tanımlamak olabilir. Seçenekler kullanılan veritabanı sürümüne göre değişir.

Benzer durum tarih ve sayı dönüşümlerinde de görülür. Filtrelenen kolonu sorgu içinde sürekli dönüştürmek yerine veri tiplerini baştan tutarlı seçmek daha sağlıklıdır. PHP uygulaması, WordPress eklentisi veya ORM katmanı sorguyu basit gösterse bile gerçek SQL’i slow query log’undan kontrol edin.

WordPress tabanlı bir VPS’te veritabanı bağlantı sorunlarını incelerken yalnızca kullanıcı adı ve parola kontrol edilmez; ağır sorgular, tablo yapısı ve disk gecikmesi de değerlendirilir. Bu konu, WordPress Veritabanı Bağlantı Hatası Nasıl Çözülür? başlığındaki bağlantı katmanı kontrolleriyle birlikte düşünülmelidir.

İndeks tasarımında güvenli uygulama sırası

Üretim sisteminde indeks eklemek, tek satırlık bir SQL komutu çalıştırmaktan daha geniş bir işlemdir. Önce yavaş sorgu belirlenir. Ardından sorgunun kaç kez çalıştığı, kaç satır döndürdüğü, tablonun büyüklüğü ve yazma trafiği ölçülür.

  1. Slow query log veya uygulama metriklerinden sorguyu seçin.
  2. Sorgunun parametrelerini gerçek üretim değerlerine yakın tutun.
  3. EXPLAIN ile mevcut erişim planını kaydedin.
  4. Benzer mevcut indeksleri SHOW INDEX veya veritabanının katalog görünümleriyle kontrol edin.
  5. İndeksi önce staging ortamında oluşturun.
  6. İndeks sonrası sorgu süresini, okunan satırları ve yazma gecikmesini karşılaştırın.
  7. Beklenmeyen plan değişiminde geri alma komutunu hazır tutun.

İndeks eklemek uygulama kodundaki kötü sorguyu otomatik olarak düzeltmez. SELECT * kullanımı, gereksiz JOIN işlemleri, sayfalama için büyük OFFSET değerleri ve N+1 sorgu problemi ayrı ayrı ele alınmalıdır. Bazen en iyi optimizasyon yeni indeks değil, daha az veri istemektir.

Veritabanı dosyalarının bulunduğu diskin türü de ölçümleri etkiler. SSD karşılaştırmaları disk gecikmesinin sorgu deneyimine etkisini anlamaya yardımcı olabilir; indeks tasarımı yine sorgu planı üzerinden yapılmalıdır. Donanım arka planı için SSD Nedir? SSD Açılımı ve HDD’den Farkları yazısına bakılabilir.

WordPress kurulumu küçükken her sorgu hızlı görünebilir. Trafik, eklenti sayısı ve içerik miktarı arttıkça aynı sorgunun maliyeti büyür. Bu nedenle yeni bir VPS kurulumunda olduğu kadar mevcut bir VPS’te WordPress Kurulumu: Adım Adım Rehber sonrasında da slow query log izleme alışkanlığı kurulmalıdır.

İndeks değişikliklerini Ansible veya migration sistemiyle kayıt altına almak da yararlıdır. Elle çalıştırılan ve unutulan SQL komutları, sonraki sunucu kurulumlarında ortamların farklılaşmasına yol açar.

Ne yapılmalı: İndeks değişikliğini migration olarak kaydedin, staging’de deneyin ve üretim sonrası plan ile gerçek metrikleri yeniden karşılaştırın.

İndeks Eklemeye Başlamadan Önce Kontrol Edin

  • Yavaş sorguyu slow query log veya uygulama metriklerinden belirleyin.
  • Sorgunun mevcut EXPLAIN çıktısını kaydedin.
  • Tablodaki mevcut indeksleri SHOW INDEX ile inceleyin.
  • Birleşik indekslerde kolon sırasını sorgu desenine göre belirleyin.
  • İndeksi önce staging ortamında oluşturup planı karşılaştırın.
  • Üretim değişikliği için geri alma komutunu hazırlayın.
  • İndeks sonrası yazma gecikmesini, disk kullanımını ve sorgu süresini izleyin.

Bir sonraki yavaş sorguda tahmin yürütmek yerine önce EXPLAIN çıktısını alın. Küçük bir plan karşılaştırması, gereksiz indeks eklemekten ve üretimde sürpriz yaşamaktan daha ucuzdur.

VPS paketlerini inceleyin

Sık Sorulan Sorular

Veritabanı indeksi nedir?

Veritabanı indeksi, tablodaki değerlere ve ilgili satırlara daha hızlı ulaşmak için tutulan yardımcı veri yapısıdır. Kitap dizinine benzer; veritabanının her satırı taramak yerine indeks üzerinden uygun kayda yönelmesini sağlar. İndeks sorguları hızlandırabilir, fakat ek disk alanı kullanır ve INSERT, UPDATE ile DELETE işlemlerinde güncellenmesi gerektiği için yazma maliyeti oluşturur.

İndeks her sorguyu hızlandırır mı?

Hayır. Küçük tablolarda tüm tabloyu okumak indeksi kullanmaktan daha ucuz olabilir. Sorgu satırların büyük bölümünü döndürüyorsa veya indekslenen kolonun seçiciliği düşükse planlayıcı tablo taramasını tercih edebilir. Kolona fonksiyon uygulanması, başında joker karakter bulunan LIKE araması ve yanlış birleşik indeks sırası da indeks kullanımını sınırlayabilir. Gerçek durumu EXPLAIN ile ölçmek gerekir.

MySQL'de indeks kullanılıp kullanılmadığı nasıl anlaşılır?

Sorgunun başına EXPLAIN ekleyerek planı görüntüleyebilirsiniz. Çıktıdaki key alanı seçilen indeksi, possible_keys kullanılabilecek indeksleri, rows tahmini okuma miktarını ve type erişim yöntemini gösterir. key boşsa bu her zaman hata değildir; fakat büyük bir tablo için rows değeri yüksekse sorgu ve tablo istatistikleri daha ayrıntılı incelenmelidir. MySQL 8.0'da EXPLAIN ANALYZE gerçek çalışma bilgisi de sağlayabilir.

Birleşik indekslerde kolon sırası neden önemlidir?

B-tree tabanlı birleşik indeksler genellikle soldan başlayan kolon sırasına göre kullanılır. (customer_id, created_at) indeksi müşteriyle başlayan filtrelerde ve ardından tarih koşulu geldiğinde etkili olabilir. Yalnızca created_at ile yapılan sorgu aynı indeksten beklenen faydayı alamayabilir. En doğru sıra, en sık çalışan sorguların WHERE, JOIN ve ORDER BY koşulları incelenerek belirlenir.

İndeks eklemek veritabanını yavaşlatır mı?

Okuma sorguları hızlanabilir, fakat indekslerin bakım maliyeti vardır. Yeni satır ekleme, mevcut satırı güncelleme ve silme işlemlerinde ilgili indeks yapıları da değiştirilir. Çok sayıda veya gereksiz indeks, yazma gecikmesini ve disk kullanımını artırabilir. Bu nedenle indeks eklemeden önce sorgu süresi, yazma trafiği, tablo boyutu ve mevcut indeksler birlikte değerlendirilmelidir.

İndeks ekledikten sonra sorgu hâlâ yavaşsa ne yapılmalı?

Önce yeni indeksin gerçekten seçilip seçilmediğini EXPLAIN ile kontrol edin. Sorgunun güncel istatistiklere sahip olduğundan, fonksiyon veya başında joker karakter bulunan LIKE ifadesi nedeniyle indeksin devre dışı kalmadığından emin olun. SELECT * yerine gerekli kolonları seçmek, gereksiz JOIN işlemlerini kaldırmak veya büyük OFFSET değerleri yerine anahtar tabanlı sayfalama kullanmak da gerekebilir. İndeks, kötü sorgu tasarımının tek başına çözümü değildir.

Kaynaklar

Defne avatarı
Yazar

Defne

vps.tc blog yazarı. Sistem yönetimi, Linux ve hosting dünyası üzerine yazıyor.