You are on page 1of 7

(http://www.aydinmahmut.com/)

 MySQL Programlama ç n Performans İpuçları


 web_dew (http://www.aydinmahmut.com/author/web_dew/)  9 Şubat 2013

 22773 okunma 2

 6 Yorum (http://www.aydinmahmut.com/mysql-programlama-icin-performans-

ipuclari/#comments)

Merhaba arkadaşlar bu dersimde sizlere önemli makalelerden birini daha paylaşacağım .MYSQL için

performans artırma yollarını sizlerle paylaşacağım.Tam olarak 10 ‘un üzerinde ipucu

yazacağım.Umarım faydası olur.Hadi başlayalım.

1-Sistem Performansı
Öncelikle sisteminizi kuracağınız makinanın RAM ve İşlemci özelliklerini elinizden geldiğince

iyileştirmeniz gerekir.Daha performanslı sunucular kullanabilirsiniz ya da

kiralayabilirsiniz.MYSQL’in sürümleri arasında da hız farkı vardır.En son sürümlerini

kullanmanız daha iyi sonuçlar verebilir.Bunun için hangi sürümün en hızlı olduğunu takip

etmenizde fayda var.

2-Uygun Tablo Yapısı Kullanmak

Yapacağınız projeye yönelik farklı tablo yapıları kullanmanız gerekir.

MySQL, iki farklı tür tablo yapısını destekler :


Transaction Tabloları :

– InnoDB

– Berkeley DB

Atomik İşlem Tabloları :

– MyISAM

– HEAP

– MERGE

– ISAM

MySQL her iki tür işlemi de desteklediği için kullanıcı,uygulamasında atomik işlemlerin hızına
mı yoksa transaction özelliklerine mi ihtiyacı olduğuna karar verebilir. Seçimler tablo bazında

yapılabilir.

Transaction’lı tablo ile atomik işlemle çalışan tablo arasındaki enbüyük fark performans

konusunda oluşur. Transactionlı tablolar çalışırken daha fazla bellek, daha fazla disk alanı ve

daha fazla işlemci gücü harcar.Başka bir pencereden bakacak olursak, sürekli “UPDATE”

yapılan veriler için farklı,sürekli “INSERT” yapılacaksa farklı bir tablo yapısı olmalıdır.Daha

da açacak olursak MYSQL tablo yapılarını incelememiz gerekecek.

*MYISAM:MYSQL’in standart tablo yapısıdır.Transaction yapısı olmadığı için çok hızlı

INSERT eder fakat veri sayısı arttıkça çok yavaş SELECT yapar.4GB’lık veri boyutundan

sonra select sorgularında verim çok fazla düşer.Ayrıca metin alanlarını indexlemek için

kullanılan full text index yapısını kullanmak için bu tablo yapısına ihtiyaç duyarız.Bu tablo

yapısının en güzel tarafı da bizi LİKE komutunun hantallığından kurtarmasıdır.Mesela sürekli


log tutmak istiyorsak da MYISAM tablo yapısına ihtiyaç duyarız.Fakat bu kadar güzel

olmasının yanısıra bir çok kötü özelliğe sahiptir.Bunladan biride yapılan her UPDATE komutu
yapının sırasını bozacaktır ve SELECT sorgularında performans düşecektir.MYISAM ile

UPDATE yapmaktan kaçınmak gerekir.Eğer sürekli UPDATE yapmamız gerekiyorsa INNODB


kullanmamız gerekir.Eğer MYISAM tablo yapısında ısrar ediyorsak tabloyu sürekli REPEAR

etmemiz gerekir.
Kötü özelliklerden bir diğeri de windows sunucuda çalışıyorsa çok güvenli olmayışıdır.Myisam,

text bazlı yapıya sahip olduğu için server üzerinde oluşabilecek aksaklıklardan dolayı tablo
yapısında bozulma olasılığı yüksektir.

*INNODB:Kayıt girilirken MyISAM gibi bütün tabloyu kitlemezler. Bu tip veritabanları özel
transaction fonksiyonlarınıda (basit olarak locking, begin ve commit olayları) çalıştırmanızı

sağlar.Sürekli UPDATE işlemleri yapılacak projelerde ve veri sayısının fazla olduğu yerlerde
performans artışı için kullanılır.Bu durumlarda BERKELEYDB tablo yapısıda kullanılabilir.Bu

iki tablo yapısının da transaction desteği vardır.İyi ve performanslı tablo yapıları olduğu için
bu iki tablo yapısını da ORACLE firması satın almış ve kendi bünyesinde geliştirmektedir.

*ARCHİVE:Adındanda anlaşılacağı gibi Arşiv niteliği taşıyan bilgilerimizi tutmak için


kullanılır.index desteği yoktur.MYISAM ve INNODB gibi standart gelen bir tablo yapısı

değildir.
*MEMORY:Bazı durumlarda verinin çok hızlı gelmesi gerekir.Mesela session bilgilerini veri

abanında istiyorsak tablo yapısını muhakkak MEMORY tanımlamamız gerekir.Ancak


unutmamamız gereken bir nokta daha var ;MEMEORY tablo yapısı veriyi RAM de

sakladığından ,fiziksel bellekle doğrudan bağı olmadığından hızlı bir şekilde çalışır.Dikkat
edilecek diğer bir hususta oluşturacağımız RAM miktarıdır.RAM boyutu 16MB’dır.Ama RAM

miktarı ayarlanabilir.
*CSV:excel kullanımı ile ilgili bir tablo yapısıdır.
Aslında 10 dan fazla tablo yapısı vardır ama tablo yapıları konumuz değil,onun için daha fazla

anlatmaya gerek yok.Sadece projemize uygun tablo yapısı seçmemiz önem arzeder.
Bir tablonun yapısını öğrenmek için

1 DESCRIBE `tablo_adi`;

kodlarını kullanabilirsiniz.Çıktı olarak her alanın adını, türünü, null olup olmadığı, indeks türü
gibi değerler döner. Kaç alanınız var ise o kadar satır çıktı alırsınız.

MySQL’deki Procedure Anlayse fonksiyonu ile bu alanların bazı betimsel istatistiklerini ve


önerilen türünü öğrenebilirsiniz. Bunun için de

1 SELECT * FROM `tablo_adi` PROCEDURE ANALYSE ();

kodlarını kullanabilirsiniz.

3-Uygun Veri Tipleri Kullanmak

Çok güncelleme yapılan tablolarda, “VARCHAR” ve “BLOB/TEXT” dinamik boylu veri


tipleri kullanılmazsa performans artışı sağlanabilir.

Veri tipleri oluşturulurken aşağıda ki kriterlere uymak gerekir.

Tp Kullanım alanı Boyut

TINYINT Çok küçük nteger S gned tanımlı durumda ken alab leceğ değerler –128 le 127

değerler ç nd r arasındadır.Uns gned tanımlı aralık 0 le 255 arasındadır.

SMALLINT Küçük nteger değerler S gned tanımlı durumda ken alab leceğ değerler –32768 le 32767

ç nd r arasındadır.Uns gned tanımlı aralık 0 le 65535 arasındadır.

MEDIUMINT Orta büyüklüktek nteger S gned tanımlı durumda ken alab leceğ değerler –8388608 le 8388607

değerler ç nd r. arasındadır.Uns gned tanımlı aralık 0 le 16777215 arasındadır.

INT orNormal büyüklüktek S gned tanımlı durumda ken alab leceğ değerler –2147483648 le

INTEGER nteger değerler ç nd r. 2147483647 arasındadır.Uns gned tanımlı aralık 0 le 4294967295

arasındadır.

BIGINT Büyük nteger değerler The s gned range s –9223372036854775808 to 9223372036854775807. The

ç nd r. uns gned range s 0 to 18446744073709551615

FLOAT Küçük (s ngle-prec s on) Değer aralıkları; –3.402823466E+38 le –1.175494351E-38, 0 arası ve

float ng-po nt değerler 1.175494351E-38 le 3.402823466E+38 arasındadır. Eğer sayının onluk

ç nd r.Uns gned olarak kısmı(v rgül önces ) atanmamışsa ya da 24 basamaktan küçük veya eş tse <=

çalışmazlar. 24 bu b r s ngle-prec s on float ng po nt değer d r. (s ngle-prec s on

(http://en.w k ped a.org/w k /S ngle_prec s on) / float ng-po nt

(http://en.w k ped a.org/w k /Float ng_po nt))


DOUBLE, A normal-s ze (double- Değer aralıkları; -1.7976931348623157E+308 le -2.2250738585072014E-

DOUBLEprec s on) float ng-po nt 308, 0 arası ve 2.2250738585072014E-308 le 1.7976931348623157E+308

PRECISION, number. Cannot be arası. Eğer sayının onluk kısmı(v rgül önces ) atanmamışsa ya da onluk

REAL uns gned basamak sayısı 25 ve 53 arasında ya da 25 veya 53’e eş tse bu b r double-

prec s on float ng po nt değer d r.

DATE Tar h Desteklenen aralık ‘1000-01-01’ le ‘9999-12-31’ arasıdır. MySQL tar hler

YYYY-AA-GG b ç m nde göster r.

DATETIME Tar h ve zaman Desteklenen aralık ‘1000-01-01 00:00:00’ le ‘9999-12-31 23:59:59’ arasıdır.

komb nasyonu MySQL DATETIME değerler n ‘YYYY-MM-DD HH:MM:SS’ b ç m nde göster r.

TIMESTAMP Zaman damgasıı Desteklenen aralık ‘1970-01-01 00:00:00’ le 2037 yılında herhang b r zaman

arasındadır.MySQL TIMESTAMP değerler n YYYYAAGGSaSaDkDkSnSn,

YYAAGGSaSaDkDkSnSn, YYYYAAGG veya YYGGAA b ç mler nde

göster r.TIMESTAMP nsert ve update şlemler nde kullanışlıdır çünkü değer

ver lmes b le şlem n yapıldığı andak tar h zaman b lg s n n t mestamp karşılığı

otomat k olarak kayded l r.

TIME Zaman Desteklenen aralık ‘-838:59:59’ le ‘838:59:59’ arasındadır. MySQL TIME

değerler n ‘HH:MM:SS’ b ç m nde göster r.

YEAR 2 ya da 4 basamaklı yıl 4 basamaklı yıl b lg s nde değer aralığı 1901 le 2155 arasındadır. 2 basamaklı

b lg s (öntanımlı 4 yıl b lg s nde değer aralığı 1970-2069 ç n 70 le 69 arasındadır.MySQL YEAR

basamaklı) değerler n YYYY formatında göster r.

CHAR A f xed-length str ng that Maks mum 255 karakter barındırab l r. Tekrar eden boşluklar değer alındığı

s always r ght-padded zaman s l n r.Öntanımlı karakter set BINARY tanımlanmamışsa CHAR

w th spaces to the değerler büyük-küçük harf duyarlılığı olmadan sıralanır veya karşılaştırılırlar.

spec f ed length when

stored

VARCHAR A var able-length str ng. Maks mum 255 karakter barındırab l r. VARCHAR değerler BINARY anahtar

Note: Tra l ng spaces aresözcüğü ver lmed ğ takd rde büyük-küçük harf duyarlılığında sıralanır veya

removed when the value karşılaştırılırlar.

s stored (th s d ffers

from the ANSI SQL

spec f cat on)

TINYBLOB, 255 karakterl b r BLOB ya da TEXT ver s

TINYTEXT

BLOB, 65535 karakterl b r BLOB ya da TEXT ver s

TEXT

MEDIUMBLOB, 16777215 karakterl b r BLOB ya da TEXT ver s

MEDIUMTEXT
LONGBLOB, 4294967295 karakterl b r BLOB ya da TEXT ver s

LONGTEXT

ENUM An enumerat on Değer l stes nden seç leb lecek her b r maks mum 65535 karakterl str ng

değerler tutab l r.

SET A set Maks mum 64 elemanlı str ng değerler kümes .

4-WHERE Şartı kullanılırken Dikkat Edilecekler


SELECT sorgusu kullanılırken birden fazla WHERE şartı kullanılacaksa bunların sırası çok
önemlidir.Mesela toplam öğrenci sayısının 300 olduğu bir tablo varsayalım.Bu tabloda

Erkeklerin sayısı 150 olsun.1.sınıfta ki öğrenci sayısı ise 60 olsun.Şimdi bu öğrenci kayıtlarının
arasından cinsiyeti erkek ve 1.sınıfta okuyan öğrencileri isteyelim.İlk WHERE şartında 1.sınıf
öğrencilerini,ikinci WHERE şartında ise cinsiyetini istememiz daha performanslı olur.Neden
derseniz ilk önce 300 kayıt içinde 60 kayıt bulacak daha sonra 60 veri içinden erkekleri

seçecek.Yani(önce 300 kayıt içinden ,sonra 60 kayıt içinden seçecek).Diğer türlü 300 kayıt
içinden önce erkekleri seçecek,daha sonra erkek olan 150 kayıt içinden 1.sınıfları
seçecek.Yani(önce 300 kayıt içinden seçecek,sonra 150 kayıt içinden seçecek).İlk sorgu daha
performanslı olur.

5-Gerekmeyen Verileri İstemeyin


Mesela,JOIN komutu kullanılacak tabloların, tablolar arası bağlantıyı kuran sütunların veri
tipleri ve veri uzunlukları birbirinden farklıysa JOIN kullanmak sorguyu çok uzatır ve
performans kaybı yaşarsınız.Ne istediğinizi bilmelisiniz.Asla işe yaramayacak verileri
istemeyin bilin ki en yaygın kullanılan JOIN tipi olan INNER JOIN iki tabloyu birleştirir ve

sadece iki tabloda da eşleşen kayıtlar varsa getirir.Eğer sadece eşleşen kayıtlar işinize
yarayacaksa INNER JOIN kullanın.
6-Sorgularda Lokal Değişkenler Kullanmak
Gerek temiz kodlama açısından gerekse iyi yönetilebilirlik ve performans açısından olsun

sorgularımız da değişkenler kullanmamız gerekir.Mesela:

1 $sorgu = mysql_query("SELECT username FROM user WHERE signup_date >= da

sorgusu yerine,tarih hesaplamasını önce bir değişkene atamamız gerekir,

1 $tarih = date("Y-m-d");
2 $sorgu = mysql_query("SELECT username FROM user WHERE signup_date >= '$

Query Cache’i kullanmak.


Çoğu veritabanı gibi MySQL’in de kendine ait bir query cache’i (sorgu tamponu var). Temel
olarak bu işlem sayesinde veritabanı aynı sorgular için her seferinde ayrı arama yapmak
yerine daha önceki sonuçlardan kullanıyor. Ama MySQL’in bu özelliği kullanmasını sağlamak
üzere bir noktaya dikkat etmekte fayda var.

1 // query cache kullanılmıyor


2 $r = mysql_query("SELECT isim FROM user WHERE dogum_tarihi >= CURDATE()

1 // query cache kullanılıyor


2 $tarih = date("Y-m-d");
3 $r = mysql_query("SELECT isim FROM user WHERE dogum_tarihi > ='$tarih'"

Curdate() gibi sonucu belli olmayan fonksiyonlar kullanıldığı zaman query cache devreye
girmiyor.

7-Resim Saklamak
Web üzerinde yazılım geliştirirken, resimleri veritabanında tutmaktansa, dosya sisteminde
resim dosyası olarak tutup, veritabanına sadece resmin nerede olduğunun bilgisini
bulundurmaya çalışın. Bir web sunucusu dosya cache’leme konusunda, veritabanı bilgisi
cache’lemekten daha başarılıdır. MySQL’in resim üzerinde arama yapma ve benzeri özellikleri
olmadığından, pratikte resmi veritabanında saklamanızın da bir anlamı yoktur.

8-EXPLAIN kullanmak
Çoğu zaman karmaşık sorgular için “explain” kullanmak performansı artırabilir. Bunun sebebi
EXPLAIN komutunun sorguları hızlandırması değil, sorgunun nasıl yapıldığını göstermesi. Bu
sayede sorgunuzu gerektiği gibi optimize edebilirsiniz.
9-Özgün sonuçlarda LIMIT 1
Belirli durumlarda tek bir özgün sonuç arıyor olabilirsiniz. Ya da sadece WHERE koşullarına
uygun kayıtlar olup olmadığını kontrol ediyor olabilirsiniz. Her iki durumda da LIMIT 1
kullanmak sorgu hızını arttırabilir.

1 // İstanbul'dan kayıt var mı?


2 // Kötüsü
3 $r  = mysql_query("SELECT * FROM user WHERE sehir = 'İstanbul'");
4 if  (mysql_num_rows($r) > 0) {
5 // ...
6 }

1 // daha iyisi
2 $r  = mysql_query("SELECT * FROM user WHERE sehir = 'Istanbul' LIMIT 1"
3 if  (mysql_num_rows($r) > 0) {
4 // ...
5 }

10-Server Özelliği
MYSQL, Linux altında daha hızlı bir performans sergilemektedir,buna dikkat etmek
gerekir.MYSQL veri tabanı ile birlikte PHP dili kullandığınız bir projenizi Apachi değilde IIS
üzerine kurarsanız hız performansı unutun derim.Ama ben IIS üzerinde de aynı performansı
yakalayabilecek ipuçları biliyorum diyen biri varsa bizimle paylaşırsa memnun olurum.
11-VIEW Kullanamak
Sıklıkla kullandığımız sorguları VIEW kullanarak yaparsak daha performanslı sonuçlar elde

edebiliriz.
View Nedir : Sorguları basitleştirmek , sorgu sürelerini kısaltmak ve sistemin daha
performanslı çalışmasını sağlamak için kullanılan sanal tablodur.VIEW sanal bir tablo olarak
işlem yapar,ancak bu sanal tabloyu daha önceden oluşturmamız gerekir.Mesela sıklıkla
kullandığımız bir sorgu olsun ve biz bu sorgunun VIEW‘ını oluşturalım.

1 //sık kullandığımız bir sorgu


2 SELECT ogrenciler.ogrenci_adi,
3        ogrenciler.ogrenci_no,
4        fakulteler.fakulte_adi,
5        fakulteler.fakulte_id
6 FROM ogrenciler
7 LEFT JOIN fakulteler
8 ON fakulteler.fakulte_id=ogrenciler.fakulte_id

Bu sorguyu daha performanslı hale getirmek için bir isim verip, VIEW oluşturalım.Kodlar şu
şekilde olacak:

1 CREATE VIEW fakulte_ogrenci


2 AS SELECT ogrenciler.ogrenci_adi,
3        ogrenciler.ogrenci_no,
4        fakulteler.fakulte_adi,
5        fakulteler.fakulte_id
6 FROM ogrenciler
7 LEFT JOIN fakulteler
8 ON fakulteler.fakulte_id=ogrenciler.fakulte_id

Kullanımı ise şu şekilde olacak

1 SELECT * FROM fakulte_ogrenci;

Bu şekilde aynı sonuçları daha performanslı alabilirsiniz.


Kullandığımız VIEW‘ı silmek içinde şu kodu kullanabiliriz.

1 DROP VIEW fakulte_ogrenci;

12-MYSQL PARTITION özelliğini kullanabilirsiniz

You might also like