SQL Index Yapısı ve Kullanımı

Gökhan Ayrancıoğlu
5 min readJul 26, 2022

Indexleme bir veritabanın tablolarındaki veriler sorgulandığında daha az veri okuyarak çok daha hızlı bir şekilde veriye ulaşmayı amaçlayan ve işlem sonucunu daha hızlı döndüren yapılardır.

Index’ler veritabanı arama motorlarının veri sorgulamayı hızlandırmak amacıyla kullandığı özel veri yapılarıdır. Basitçe bir index, indexlenmek istenen tablodaki istenilen sütun verilerini (pointer)işaretler. Klişe ama çok açık bir örnek olarak kitaplardaki index/içindekiler kısmı göz önüne alınabilir.

Bir index SELECT ve WHERE ifadeli sorguları hızlandırmaya yardım ederken INSERT ve UPDATE operasyonları gerçekleştirilirken ek bir adım gerektiği için veri yazmayı yavaşlatmaktadır.

Tek index’li bir tabloda bir yazma işlemi (INSERT ya da UPDATE) gerçekleştirirseniz, aslında iki tane işlem yapmış olursunuz. Biri tablo verisini yazmak ya da güncellemek için diğeri ise index’i yazma ve düzenleme için yapılır. Index işleminde index verileri sıralama tipine göre yeniden düzenlenir.

NOT: Indexleme işlemi her veritabanında farklılık gösterebilir. Burada gösterilen örnekler POSTGRESQL baz alınarak yazılmıştır.

Genellikle CREATE INDEX ifadesiyle oluşturulan bu indexlere özel bir isimlendirme yapılabilir ve ASC, DESC gibi sıralama tipi verilebilir. Oluşturulan index, verilerin üzerinde herhangi bir değişiklik yapmadan gerçekleştirilmektedir.

Unutmayın ki veriyi hızlı çekmenin tek ve en doğru yolu indexleme olmayabilir. Veritabanımızın index yapısı kurarken dikkatli olmalıyız.

Verimiz belirlediğimiz index yapısına göre işaretlenir ve bir düzen içerisinde sıralı bir biçimde tutulur. Yani bir veri kaydedilirken/güncellenirken index’lediğimiz sütun üzerinden bir işlem adımı daha eklemiş oluruz. Index’imiz üzerinden sorgu gerçekleştirdiğimizde de tüm veriler üzerinden değil indexler üzerinden bir okuma işlemi gerçekleştirmiş ve daha hızlı bir veri okuma yapmış oluruz.

Index Nasıl Çalışır?

Indexleme işlemini bir örnek üzerinden açıklamak, çalışma mantığını kavramaya yardımcı olacaktır. 500.000 kayıt bulunan bir user tablomuz olduğunu varsayalım. Bu tablodaki email sütunuyla ilgili oldukça fazla sorgulama/okuma işlemi olduğunu düşünelim.

Örnek veri seti
SELECT * FROM users WHERE email = 'ira.wolford@ntlworld.com';

email sütunu için herhangi bir index olmadığından, veritabanı motorunun ilgili kullanıcıyı aramak için user tablosunun tümünü taraması gerekiyor.

Bütün tabloyu taramak, tablo yapısı büyüdükçe sorgunun sonuca ulaşmasını geciktirir ve daha fazla zaman alır. Günümüzde özellikle orta ve büyük ölçekli projelerde sorgulama işlemi her geçen gün zaman maliyeti yaratmaktadır. Bu sorunu çözme yöntemlerinden biri index kullanmaktır.

User tablosunun email sütunundaki değerler için index’imizi aşağıdaki ifadeyi kullanarak oluşturabiliriz. Böylece sürekli okuma işleminde kullandığımız WHERE koşuluna uygun bir index yaratmış oluruz.

CREATE INDEX idx_users_email ON users(email);

Oluşturduğumuz index ile birlikte her oluşan yapı için temelde aşağıdaki gibi bir betimleme olduğu varsayılabilir.

Şimdi, sorguyu yeniden çalıştırdığımızda aradaki müthiş farkı görebilirsiniz. Veritabanı motorunun arama için index kullandığını düşünürsek, sorgunun çok daha hızlı yanıt verdiği aşikardır.

İlk sorgumuz ~244 ms sürerken index’lediğimizde bu sorgunun yanıt süresi ~54 ms’ye düşmüş oldu.

Ufak bir not olarak; bir tabloda birden fazla sütun için index oluşturulabilir.

CREATE INDEX idx_user_names ON people (last_name, first_name);

Gereksiz ya da yanlış tanımlanmış index’leri yok etmemiz gerektiğinde ise;

DROP INDEX idx_users_email

komutu çalıştırılabilir. Böylece varolan index’ten kurtulmuş oluruz. Örneğimiz için oluşturduğumuz index’i sildiğimizde sorgumuz yine eskisi gibi yavaş çalışmaya devam edecektir.

Indexler Ne Zaman Kullanılmalı?

Index’ler çoğu zaman performans açısından fayda sağlıyor. Burada dikkat edilmesi gereken hüsus index’lenen sütunun doğru seçilmesidir. Listede bulunan maddelerin ortak kümesi “sorguda çok sık kullanılan sütunlar” ya da “çok hızlı ulaşılması amaçlanan veriler” için geçerli olmasıdır.

  • Sorgularınız istenilenden çok daha geç cevap dönüyorsa,
  • Sorgularınızda koşul içerisinde sürekli kullanılan bir sütun var ise,
  • Sorgulanan sütunda çok farklı değerler var ise ve fazla NULL değer içermiyorsa,
  • Bir veya daha fazla sütun, sıklıkla bir WHERE ifadesiyle veya bir join işlemi ile birlikte kullanılıyorsa

Indexler Ne Zaman Kullanılmamalı?

Index’lerin ana amacı veritabanının performansını arttırmak olsa da, kullanmamanın daha yararlı olacağı ya da çok dikkatli kullanılması gerektiği durumlar vardır. Bunlar sadece önerilerdir, kullanım şekilleri ve sorgu tiplerine göre bazı şartlar görmezden gelinebilir.

  • Küçük tablolar için kullanımı önerilmez.
  • Sorgu koşulu olarak çok sık kullanılmayan sütunlar için kullanımı önerilmez.
  • Çok fazla “NULL” verisi bulunan tablolarda kullanımı önerilmez.
  • lgili sütunda aynı veriden fazla sayıda var ise, index kullanımı tavsiye edilmez. Örneğin; “email” alanının yüzde 20'si aynı mail adresi verisi içeriyor ise performansı istenilen kadar verimli olmayacaktır. (Madde için çok teşekkürler, Muhammed Hilmi Koca)
  • Yazma oranı, okuma oranından çok daha fazla olan tablolarda önerilmez.
  • Sık ya da büyük toplu güncelleme veya ekleme işlemlerine maruz kalan tablolarda kullanımına çok dikkat edilmelidir.
  • Sıklıkla değişikliğe uğrayan tablo sütunlarında kullanımına dikkat edilmelidir.

Index Kullanırken Nelere Dikkat Edilmeli?

Gereksiz index kullanımı, gereksiz yük getirecektir. İlk olarak veriyi yazarken ekstra bir işlem adımı eklemiş oluruz. Indexlerimiz çoğaldıkça yazma hızımız azalacaktır. Bir diğer performans faktörü ise index sayımız arttıkça gereksiz indexlere göre de tarama yapılabileceği için okuma hızımızdan da istediğimiz performansı alamayabiliriz.

Sık kullanılmayan ya da okuma oranı yazma (INSERT ve UPDATE) oranından çok daha düşük olan indexleri silmek, gereksiz yük ve performans kayıplarından bizi kurtarır.

Fazla sayıda index içeren tablolarınızın olması veritabanınıza ek bir yük getirebilir. Fazla indexleme işlemi düşündüğünüzden çok daha fazla disk alanı da kaplar. Tablolarımız çok çok büyüdüğünde yine indexler bizim için çare olmayacaktır.

Söyleye söyleye dilimde tüy bitse de sonuca varmak adına indexlemenin doğru kullanımı, sorguların süresini büyük ölçüde azaltabilir :) Her index kullanımı ise performans açısında bir avantaj sağlamayabilir. Yanlış indexleme, sorguların hızını artırmak yerine özellikle yazma performansında azalmaya neden olabilir. Indexlerin doğru kullanımı size hız getirecektir.

— Beni Medium’da takip edebilir, Twitter ve , Linkedin’den ulaşabilirsiniz.

— 1:1 görüşmeler için: Superpeer

gokhana.dev

--

--

Gökhan Ayrancıoğlu

Software Engineer @Yemeksepeti • #Java • #Spring Boot • #Kotlin • #Spark • #Microservices • https://gokhana.dev