ProgramlamaSQL/Veritabanı geliştiricisi

SQL'de indekslerin çalışma şeklini açıklayın. Onlar sorguları nasıl hızlandırır ve hangi durumlarda kullanımları tersine sistemi yavaşlatabilir?

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap

İndeksler — belirli bir sütun veya sütunlar seti için verilerin hızlı bir şekilde aranmasını sağlamak amacıyla kullanılan özel veri yapılarıdır (genellikle B-ağaçları tabanlıdır). İndeksler, taranan satır sayısını azaltarak seçim, sıralama ve filtrelemeyi hızlandırır.

İndeks türleri:

  • Sıradan (B-tree, hash)
  • Bileşik (çok sütunlu)
  • Benzersiz (değerlerin benzersizliğini sağlar)
  • Kapsayıcı (covering)
  • Tam metin (full-text)

İndeksler hızlandırır:

  • WHERE ... = ...
  • İndeksli sütun üzerinde JOIN
  • İndeksli sütun üzerinde ORDER BY ve GROUP BY

Yavaşlatabilir:

  • Ekleme, güncelleme, silme — indeksler, yapılarını korumak için ek işlemler gerektirir.
  • Eğer sorgular sıklıkla indeksin olmadığı sütunları kullanıyorsa, indeksler faydasız olur ve toplu eklemelerde zararlı bile olabilir.

İndeks oluşturma örneği:

CREATE INDEX idx_user_email ON users (email);

İndeksin yardımcı olmadığı örnek:

SELECT * FROM users WHERE lower(email) = 'test@example.com'; -- eğer indeks email üzerinde oluşturulmuşsa, ancak sorgu lower(email) fonksiyonunu kullanıyorsa, indeks kullanılmaz!

Kandırmaca soru

Tablonun tüm sütunlarına indeks eklenirse, her zaman tüm SELECT sorgularının yürütülmesi hızlanır mı?

Cevap:
Hayır. İndeksler yalnızca filtreleme veya sıralama indeksli sütun üzerinde kesin olarak gerçekleştiğinde sorguları hızlandırır; fonksiyonlar veya indeks kullanımını engelleyen işlemler uygulanmadığında. Aşırı sayıda indeks, INSERT/UPDATE/DELETE işlemlerini yavaşlatmanın yanı sıra çok fazla alan kaplar; bazı karmaşık sorgular ise indeksleri hiçe sayabilir (örneğin, bir ifade ile aralık taraması sırasında).

Örnek:

SELECT * FROM orders WHERE year(order_date) = 2023; -- eğer yalnızca order_date üzerinde bir indeks varsa, year() fonksiyonu nedeniyle indeks çalışmaz

Hikaye

Elektronik posta sisteminde, sık kullanılan her alan için bir indeks oluşturan bir tetikleyici oluşturuldu. Altı ay sonra sistemin performansı düştü — her ekleme veya satır değişikliği için 4-5 kat daha fazla zaman harcanıyordu. Denetimden sonra, indeks sayısı azaltıldı, sistem hızlandı.


Hikaye

Reklam platformunda, sıkça substring(url, 1, 10) ile filtrelenmiş SELECT sorguları vardı. URL üzerinde indeks olmasına rağmen, SQL substring fonksiyonu nedeniyle indeksi kullanmadı. Çözüm, bu tür seçimler için ayrı bir alan ve üzerine indeks eklemek oldu.


Hikaye

Sadakat programında, (customer_id, shop_id) alanları üzerinde bileşik bir indeks oluşturuldu. Yalnızca shop_id bazında yapılan sorgularda indeks uygulanmadı ve tablo tamamen tarandı (full scan) oldu. Bu, bonus hesaplamaları sırasında indeksin faydasını kaybetmesine neden oldu. Optimizasyon: shop_id için ayrı bir indeks oluşturmakla sağlandı.