- enterId:146615 Mysql’de indexleme « KOODLA | BLOG

Mysql’de indexleme

Date06 / Nisan / 2008 Author İsa Engiz    Category mysql     Tags , Yorumlar6 Yorum Yapilmis.

Yazdığımız bir veritabanı-PHP uygulamasının ardından genelde sorgularımız hızlı çalışır, çünkü veritabanımız henüz yenidir ve çok fazla veri yoktur, MYSQL sunucusunun istenen veriyi bulmak için tüm tabloyu tarayıp sonucu geri döndürmesi fazla uzun sürmez.

indexleme kod resmi

Ancak zamanla, veritabanımıza yeni veriler eklendikçe sorgularımızın sonuçlarının yavaş döndüğünü fark ederiz. Bu durumda yapılabileceklerden biri ve aynı zamanda en etkilisi indexleme yapmaktır.

Bu yazımızda Mysql tablolarımızda nasıl indexleme yapacağımızdan, hangi durumlarda indexlemenin iyi olduğundan ve biraz da dezavantajlarından bahsedeceğiz.

İndexleme nedir?

İndex, tablolarda bulunan sütunlarının bazılarının özel şekilde düzenlenmiş halidir. Bu alanların özel düzenlenmesi sayesinde sorgular daha hızlı çalışır ve geriye daha çabuk sonuç döner.

Küçük bir örnek

Burada iki örnekten bahsedeceğiz ve indexlemenin bize nasıl hız kazandırdığını anlamaya çalışacağız.
Birinci örneğimizde şöyle bir tablomuz olsun:

id
isim
1 isa
2 mustafa
…. ….
999 ali
1000 osman

Bu örnekteki tablomuzda sadece id ve isim diye iki alanımız bulunmakta ve ve tam olarak 1000 satır kaydımız var. Eğer şöyle bir sorgu yapmak istiyorsak:

SELECT * FROM tablo WHERE isim='osman'

Bu sorgu çalıştırıldığında MySQL, bütün tabloyu tarar ve ‘osman’ kaydını bulur, sonuç olarak bunu geri döndürür. Biz burada yapacağımız indexleme ile bu sorgunun çok daha hızlı şekilde gerçekleşmesini sağlayabiliriz, “isim” sütununda yapacağımız bir indexlemeden sonra, MySQL bu sütundaki verilerin otomatik olarak alfebatik sıraya dizildiği bir index yaratacaktır:

index
ali
….
….
zeynep

Böyle bir indexlin tabloda varolması durumunda MySQL “osman” kaydının hangi satırda olduğunu direk olarak bulabilecek ve sorgumuzun sonucu çok daha hızlı şekilde gelebilecektir.

İndexlemenin sunduğu hız belki de böyle bir tabloda çokda açığa çıkmayabilir, çünkü MySQL zaten böyle bir sorgu için yeterince hızlıdır, ama ilişkili veritabanlarında farkını hemen ortaya koyar.

3 tane tablomuz olduğunu düşünelim, tablo1, tablo2, tablo3. Her tabloda 3 tane sütun olduğunu varsayalım, alan1, alan2, alan3. Bu alanlarda sayılar saklıyor olalım (1′den 1000′e kadar) ve her tablomuzda 1000 tane kayıt olsun.
Aşağıdaki sorguyu çalıştırırsak:

SELECT tablo1.alan1, tablo2.alan2, tablo3.alan3
FROM tablo1, tablo2, tablo3
WHERE tablo1.alan1 = tablo2.alan2 AND tablo2.alan2 = tablo3.alan3

Bu sorgu, her tabloda aynı değeri taşıyan satırları geri döndürecek ve yaklaşık 1000 tane kayıt elimizde olacak. Ancak MySQL bunu yapabilmek için yaklaşık olarak 1000*1000*1000= 1 milyar satırı taramak zorunda kalacak. Bu, oldukça zaman alır.
Ancak tablo2.alan2 ve tablo3.alan3 sütunlarında oluşturacağımız indexler ile bu sorgunun çok daha hızlı çalışmasını sağlayabiliriz. MySQL öncelikle tablo1.alan1 sütunundaki verileri tek tek tarar, tablo2.alan2′deki indexden faydalanarak eşleşen değeri hemen bulabilir ardından tablo3.alan3 sütunundaki indexi kullanarak aynı değeri yine hemen çekebilir. Böylece toplamda 1000 satır taranmış olur. (1milyon kat daha az satır!)

Bu iki örnek sadece indexlemenin bize nasıl fayda sağlayacağını göstermek içindi. Şimdi kodlama kısmına geçelim ve bir sütunda nasıl kolayca index oluşturabileceğimizi görelim.

Nasıl index oluşturalım?

Bir tablonun alanında index oluşturmak istiyorsanız, şöyle küçük bir sorgu yazmalısınız:

ALTER TABLE tablo_ismi ADD INDEX index_ismi (index_sütunu_ismi);

İşte böylece index yaratmış oluyoruz.

Aşağıdaki gibi bir tablomuz olduğunu düşünelim:

id isim soyisim yas cinsiyet telno
…… …… …… …… …… ……
…… …… …… …… …… ……

Bu tabloda şöyle bir sorgu çalıştırmak istiyorsak:

SELECT * FROM tablo WHERE isim='isa';

bu tabloda “isim” alanında index oluşturmak sorgunun sonucunun daha hızlı dönmesini sağlayacaktır:

ALTER TABLE tablo ADD INDEX isim_indexi (isim);

Böylece tablomuzda eğer 10 000 satır varsa, bu sorgu çalıştırıldığında MySQL tüm satırlara tek tek bakmak yerine oluşturulmuş olan indexi kullanıp sonucu çabucak geri döndürecektir.

Elimizde şöyle bir sorgu olduğunu düşünürsek:

SELECT * FROM tablo WHERE isim='osman' AND soyisim='akşit' AND yas='35';

Bu durumda az önce oluşturduğumuz index işimize yaramayacaktır. Ama bunu da aşabiliriz, soyisim ve yas alanları için de index oluştururuz ve böylece sorun halledilmiş olur değil mi?

Hayır! MySQL her tabloda yalnıca bir index oluşturulmasına izin vermekte. Ama aynı zamanda bir indexde birden fazla alanın indexlenmesine de izin vermekte! O halde şöyle bir index işimizi görecektir:

ALTER TABLE tablo ADD INDEX isim_soyisim_yas (isim, soyisim, yas);

Böylece “isim”_soyisim_yas” adında bir index oluşturduk ve yukarıdaki sorgumuz artık daha hızlı çalışabilecek!

Oluşturduğumuz bu çok sütunlu index’in bir faydası daha var, bu index ile aslında 3 adet index oluşturmuş olduk:

-isim, soyisim, yas
-isim, soyisim
-isim

Yani oluşturduğumuz index, daha evvel “isim” alanı için oluşturduğumuz indexin de yapmış olduğu işi yapacak. İyi seçilmiş bir indexin böyle bir avantajı da var.

Belki de “iyi seçilmiş” kelimesinin altını çizmek gerekir, çünkü hangi sütun için index oluşturacağınıza karar vermelisiniz.

Hangisini indexlemeliyim?

Hangi sütunda indexleme yapacağınıza aslında sizin ihtiyaçlarınız yön veriyor. Sık sık yazdığınız sorgu cümleleri, aramalarda kullanılacak alanlar genelde index için uygun alanlar olurlar.

Where

İndexleme için en güzel aday sorgu cümlelerinde “WHERE” kelimesinden sonra yazdığınız alanlardır. Yazdığınız sorgu cümlelerinde bu şekilde öne çıkan bir sütun varsa o sütun index oluşturmak akıllıca olacaktır.

Farklı değerler

İndexleme için bir diğer aday sütunlar ise, içlerinde farklı değerler tutan alanlardır. Yukarıdaki tablomuzu düşünürsek, “cinsiyet” alanı indexleme için pek de uygun sayılmaz, çünkü tutabileceği iki farklı değer vardır, “E” veya “K”. Bu alanda bir index oluşturulsa bile MySQL yine de toplam satırların yarısını taramak zorunda kalacaktır, bize pek performans getirisi sağlamaz. Bunun yerine hemen hemen her satırda farklı değerlerin tutulduğu sütunlar indexleme için kullanışlı olabilirler.

İndex’in dezavantajları

İndexleme, doğru kullanıldığında yavaş sorguları oldukça hızlandırabilir. Ancak bir-iki küçük dezavantajını da söylemeliyiz.

İlki indexleme, sabit diskte extra yer tutar. Verdiği performans artışının yanında karşılaştırılabilecek kadar bile değildir ancak veritabanınınzdaki her tablonun her sütununda index oluşturursanız, sabit diskinizin umduğunuzdan çok daha çabuk dolduğuna şahit olabilirsiniz!

İkincisi ise indexleme INSERT, UPDATE ve DELETE komutlarının çalıştırılma sürelerinde yavaşlamaya neden olur. Yine bu yavaşlamanın gözle görülür bir fark olduğu söylenemez, ama MySQL’in tablolarda INSERT, UPDATE ve DELETE ile güncelleme yaparken index alanlarını da uygun şekilde güncellediğini unutmamak gerekir. (Yani her tablonun her sütununu indexlememek gerekir!)

Sonuç

İndexleme aslında, sorgularımızı hızlandırmak için yapılabileceklerden biridir sadece, ama en önemlisidir, yavaş çalışan sorgulara yönelik uygun indexleme yapılırsa, sorgu hızında çarpıcı artışlar gözlenebilir.

Daha sonraki yazılarda MySQL’de performans artışını sağlayabilecek başka konulara da fırsat bulabilirsek değiniriz.
Bir sonraki yazıda görüşmek üzere!

Not:İndexleme üzerine şu yazılara da göz atmayı düşünebilirsiniz:

-http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html
-http://www.informit.com/articles/article.aspx?p=377652
-http://www.databasejournal.com/features/mysql/article.php/1382791
-http://www.sitepoint.com/print/optimizing-mysql-application

Ya da Koodla | Blog’daki diğer MySQL yazılarına bakabilirsiniz.

- Bu blogda yer alan yazıları RSS ile takip edebilirsiniz. RSS aboneliği için tıklayın.

- Ya da bu blogda yer alan bütün yazıları içindekiler sayfasında görüntüleyebilirsiniz. Tıklayın!

Mysql’de indexleme yazısına 6 Yorum yapılmış.

  • faruk 06 Nisan 2008, 20:43

    teşekkürler, baya detaylı açıklamışsınız….

  • osman 14 Eylül 2008, 06:04

    güzel yazı. elinize sağlık

  • seçkin 02 Ocak 2009, 02:06

    İndexlemenin avantajlarından bahsetmişiniz.Oluşturmuş olduğumuz tablolarda bazı özel alanları primary_key yapıyoruz.Mesala kitap tablosunda kitapno gibi.Bu işlemle mysql veritabanında indexleme yapmış olurmuyuz.Yoksa ekstra idexleme yapmak için sorgumu yapmalıyız?

  • İsa Engiz 02 Ocak 2009, 10:26

    bir alanı primary_key olarak tanımlamak ayrıca o alan üzerinde index oluşturmak demektir. Dolayısıyla o alan için yeniden index oluşturmaya gerek yoktur.

    Ama “where” kelimesinden sonra sık kullandığımız alan primary_key olarak tanımladığımız alan değilse, sık tekrarlanan alan için de index oluşturmak sorguları hızlandıracaktır.

  • mirc 09 Ocak 2009, 11:23

    tskler..

  • kaan 14 Temmuz 2010, 02:08

    her sorgunun başına index oluşturma kodunu koymamız gerekli mi?

Arama


E-Posta Aboneliği


RSS Aboneliği

En Çok Yorumlanan Yazılar

Etiketler

404 ajax apache arama butonu as astrofizik açık kaynak banner blogger blogger/blogspot Blogger / Blogspot blogspot case chmod css date dosya yükleme editör etiket etkinlik favicon featured form ftp galeri Genel gimp hata sayfası header htaccess htpasswd ilişkisel veritabanı index innodb javascript join JQuery kategori koodla linux mysql opacity php resim url

Son Yorumlar

  • Murat: Güzel bir teknik, şu ana kadar sınırsız alt kategori lazım olmadı ama olmayacağı anlamına gelmiyor :)
  • iilyas: Bu kodlar çalışmıyor arkadaşım. Localde olduğu içinmi acaba ?
  • iilyas: Arkadaşım çok teşekkür ediyorum. Harika anlatmışsın ajaxla çalışmalara başlamak lazım estetik açısından.....
  • Nuri: bende bu şekilde bir çalışma yaptım ancak bir sorunum var ne yaptıysam url den index.php bölümünü kaldıramadım....
  • Kemal: Makale için çok teşekkürler, resimleri div tagları ile yapabilirmiyiz. Bu arada imagelara link verirsek daha...

Sayfalar


Faydalı Bağlantılar