Veritabanı Optimizasyonu

Bu makalede MySQL’i daha az yormak, sorguların işleniş zamanlarını kısaltmak, sitenizi hızlandırmak için birtakım veritabanı optimizasyonu tavsiyelerinde bulunacağım.

Eğer kendi kodlamalarınızla veritabanı kullanacaksanız birçok mysql sorgusu ile boğuşmak durumunda kalabilirsiniz. Kullandığınız tablolar çok fazla veri içerebilir. MySQL sunucusu bu verileri işlerken tüm veritabanındaki bilgileri kontrol etmek zorunda kalıyor olabilir. Şimdi ideal bir sorgu yapısını örnekleyelim:

1. Sadece gerekli sütunları sunucudan isteyin:

Tüm sütunları istemek demek, MySQL sunucusunun fazladan ve gereksiz veri göndermesi demektir. Örneğin bir tablodaki sadece başlık ve tarih kısmını kullanmamız gerekiyorsa bunu SELECT [sütunlar] bölümünde belirtmeliyiz.

# Yanlış Kullanım:
SELECT * FROM haberler LIMIT 0, 10;

# Doğru Kullanım:
SELECT baslik, tarih FROM haberler LIMIT 0, 10;

2. ORDER BY rand() kullanımından kaçının.

Gelen verilerin sırasını bildirmemize yarayan ORDER BY komutunun yanında eklenen rand() verilerin rastgele getirilmesini ister. Fakat bu özellikle binlerce kayıt bulunan bir tabloda sunucuya extra yük bindirir. Yaklaşık 120000 kayıtlı bir tabloda rand() kullanırsak en az 0.3 saniye sürecektir sorgumuz. Oysa ideal bir sorgu 0.001-0.005 ms harcamalıdır.

# Yanlış Kullanım:
SELECT * FROM sarki_sozleri ORDER BY rand() LIMIT 0, 10;

Eğer illa ki rastgele veri almak istiyorsanız, bu işi PHP’de de yapabileceğinizi unutmayın. Böylelikle yük MySQL’den kalkacaktır.

3. INDEX kullanın.

MySQL’de verileri hızlı bir biçimde sıralamak ve karşılığında gelen veriyi bulmak için INDEX yaratmalıyız. Özellikle en çok kullanılan sütunlar için INDEX yaratırsak sunucu daha az zamanda verileri bulacaktır:

İki yolla index ekleyebilirsiniz:

# 1. Yol
ALTER TABLE tablo_adi ADD INDEX index_adi (sutun1, sutun2, ...);

# 2. Yol
CREATE INDEX index_adi ON tablo_adi (sutun1, sutun2, ...);
# Örneğin aşağıdaki tarz bir sorguyu sıkça kullanıyorsak:
SELECT baslik FROM haberler WHERE dosya = "dosya_adi" AND kategori = "1";

# Aşağıdaki gibi bir index yaratma yoluna gidebiliriz:
CREATE INDEX l_dosya_kat ON haberler (dosya, kategori);

Böylelikle bu tarz sorgular daha az zaman harcayacaktır.

Eğer tablodaki CHAR, VARCHAR, TEXT gibi yazı içeren verilerde LIKE “%kelime%” tarzı aramalar gerçekleştiriyorsanız. FULLTEXT INDEX’i kullanabilirsiniz.

# Şarkı sözü tablomuzda sözlerin bulunduğu sütuna bunu ekliyoruz.
CREATE FULLTEXT INDEX l_sozler ON sarkisozleri (sozler);

# Ve eğer sözlerde arama yapacaksak bunu kullanmamız yeterli:
SELECT isim, soz FROM sarkisozleri WHERE MATCH(sozler) AGAINST('kelime');

Yukarıdaki örnek çalıştırılsaydı içinde “kelime” geçen tüm şarkı sözleri sorgu sonucu olarak yansıtılırdı.

Umarım sizlere faydalı olur bu yazı.

Unutmadan HTML Dersleri sayfamızdan sonra MySQL Komutları sayfamız da tamamlandı. Veritabanları ile ilgili yardım için bu siteyi kullanabilirsiniz.

MySQL’de Inner Join Kullanımı

Bazı durumlarda bir MySQL veritabanındaki tablolarımızı bir arada kullanmamız gerekir. Sadece yazı ve kategori numaralarının bulunduğu bir tabloda, kategori numarasına karşılık gelen kategorinin adını almak için başlıkta bahsettiğimiz INNER JOIN … ON() kodunu kullanarak istediğimiz bilgileri tek bir sorguyla alırız. Bu komut yapısı şu şekildedir:

SELECT (alacağımız veriler) FROM tablo1 INNER JOIN tablo2 ON (kurallar);

Alacağımız veriler bölümünde gerekli olan sütun adlarına aralarına virgül koyarak yer veririz. Kurallar bölümünde ise klasik bir WHERE … sonu gibi hangi kurallar dahilinde işlemin yapılacağını belirleriz.

SELECT etiket_id, baslik FROM etiketler_yazi INNER JOIN etiketler ON etiket_id=etiketler.id;

Yukarıdaki örnekte etiketler_yazi tablosundan etiket_id değeri, etiketler tablosundan ise baslik değerini aldık. En son kurallar kısmında “etiketler.id” kullanımı dikkatinizi çekmiş olabilir. Burada her iki tablo da id değerine sahip olduğunu düşünerek hangi tablonun id değerini alacağını bildirdik. tabloadi.sutunadi şeklinde bu kullanım sayesinde MySQL’e hangi sütundan bahsettiğimizi anlatmış olduk.

Bunun gibi aynı sütun adına sahip değerlerde “tabloadı as takmaad” şeklinde özel olarak isimlendirme şansına da sahipsiniz. Eğer bu şekilde verileri alacak olsaydık:

SELECT t1.etiket_id, t2.baslik FROM etiketler_yazi as t1 INNER JOIN etiketler as t2 ON t1.etiket_id=t2.id;

Yukarıdaki kod ile bu kod aynı işlevi görüyor. Tek farkı burada özel isimlendirilmelere gidilerek MySQL ile kesin olarak bir anlaşma sağladık. Benzer sütun adları için de “t1.id as id2” şeklinde isimlendirmelere gidilebilir. Bir sorgu sırasında sonuçlarımızdaki sütun adı burada belirttiğimiz id2 değerini alacaktır.

Kolay gelsin…

MySQL Komutları

Açık kaynak veritabanı sistemi MySQL ile anlaşabilmek için çeşitli komutlar kullanmaktayız. Bunlar bir veritabanı yaratmaya, silmeye, tablo oluşturmaya, seçmeye, düzenlemeye ve silmeye yaramaktadır. Şimdi bunlardan en çok kullanılanları ve en önemlileri burada sizlerle paylaşalım.

Öncelikle bir veritabanı (database) yaratmak için kullandığımız CREATE komutu. Bu komut, eğer yetkiliyseniz belirtilen isimde veritabanı yaratmanızı sağlar. Veritabanı, tabloları kapsayan en büyük depolama birimidir.

CREATE DATABASE veritabani;

Bir veritabanı, içindeki tabloları ve tüm bilgilerini silmek içinse DROP DATABASE’yi kullanmaktayız. Yarattığımız “veritabani” isimli veritabanını silmek istersek:

DROP DATABASE veritabani;

Komutu ile bu işlemi gerçekleştiririz. Veritabanının küçük depolama birimleri olan tabloları da CREATE ve DROP ile oluşturur, fakat bu kez DATABASE yerine TABLE deyimi kullanırız.

CREATE TABLE tabloadi (
'id' INTEGER(5) UNSIGNED NOT NULL AUTO_INCREMENT,
`kategori` INTEGER(4) UNSIGNED NOT NULL,
`isim` VARCHAR(45) NOT NULL,
`detaylar` TEXT NOT NULL,
PRIMARY KEY(`id`)
)
TYPE = MYISAM;

Burada parantez içerisinde tablomuzu oluşturan sütunlar ile ilgili bilgileri gireriz. Tek tırnak içindekiler sütun adlarıdır. Sonraki kullanılanlar ise o sütunun özellikleri. INTEGER(Boyut) sayısal bir değer, VARCHAR(boyut) ya da TEXT ise alfasayısal bir değeri ifade eder. DOUBLE ise ondalıklar ve negatifleri de kullanabildiğimiz sayısal ifadelerdir. NOT NULL, sütunun asla tanımsız olamayacağını, AUTO_INCREMENT her yeni kayıtla değerin artacağını (bu işlem otomatik yapılır), PRIMARY KEY hangi anahtarın öndeğer olduğunu (öncelikli) belirtir. En sonda kullanılan MyISAM (ya da InnoDB) ise tablo türünü belirtmemize yarar. Tabloyu silmek içinse DROP kullanılır:

DROP TABLE tabloadi;

Ve şimdi nasıl kayıt ekleyip, düzenlediğimizden ve sildiğimizden bahsedelim. Kayıt eklemek için INSERT INTO deyimini kullanırız.

INSERT INTO tabloadi (sutun1, sutun2) VALUES('deger1', 'deger2');

Burada ilk parantezde sütun adları, VALUES() içerisinde ise o sütuna karşılık gelecekleri yazdık. Eğer tüm sütunları içeren bir komut kullanıyorsanız sütunların sırasına göre yazabilirsiniz.

INSERT INTO tabloadi VALUES('deger1', 'deger2');

Bir kayıttaki değeri UPDATE komutu ile değiştiririz:

UPDATE tabloadi SET sutun1='deger1', sutun2='deger2' WHERE kosul1='kosul2';

Buradaki koşul belirtilirken klasik IF – ELSE deyimlerinde olduğu gibi eşleştirmelere gidilir. Mesela id anahtarı 4 olan veride güncelleme yapacaksak koşulumuz id=’4′ olacaktır. Birden fazla koşul belirtiyorsak ve için AND, veya için OR kelimelerini aralarına getiririz, örneğin id=’4′ AND kategori=’2′ gibi.

Bir kaydı silmek için koşul belirterek aşağıdaki komutu kullanırız:

DELETE FROM tabloadi WHERE sutun1='kosul';

Eğer tüm kayıtları sileceksek WHERE ve sonrasını yazmayarak bu işlemi yaparız. Böylece o tablodaki tüm kayıtlar silinecektir.

Kayıtları seçmek, listelemek içinse SELECT komutu kullanırız. Bu kodun kullanımı aşağıdaki gibidir:

SELECT sutun1, sutun2 FROM tabloadi WHERE sutun1='kosul' ORDER BY sira LIMIT 0, 10;

Belirtilen komuttaki SELECT sutun1, sutun2 hangi sütunların seçime dahil edileceğini belirler. WHERE ile hangi koşula bağlı kayıtları listeleyeceğimizi anlatırız. ORDER BY sira, kayıtların neye göre sıralanacağını. Buraya bir sütun adı gelir. Eğer sayısal ise küçükten büyüğe, ORDER BY sutun1 DESC dersek büyükten küçüğe. Alfasayısal ise A’dan Z’ye, DESC varsa sonunda Z’den A’ya sıralar. LIMIT 0, 10 olarak belirttiğimiz ise kaç kayıt listeleneceği ve nerden başlanacağı. Burada ilk kayıttan başlanıp 10 kayıt listelenir. LIMIT 10, 20 dersek. 10. kayıttan başlar ve 20 tane sıralar.

Sevgilerimizle…
Venus Programlama