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

    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

    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.

    Tip
    Kullanım alanı
    Boyut
    TINYINT
    Çok küçük integer değerler içindir
    Signed tanımlı durumda iken alabileceği değerler  128 ile 127 arasındadır.Unsigned tanımlı aralık 0 ile 255 arasındadır.
    SMALLINT
    Küçük integer değerler içindir
    Signed tanımlı durumda iken alabileceği değerler  32768 ile 32767 arasındadır.Unsigned tanımlı aralık 0 ile 65535 arasındadır.
    MEDIUMINT
    Orta büyüklükteki integer değerler içindir.
    Signed tanımlı durumda iken alabileceği değerler  8388608 ile 8388607 arasındadır.Unsigned tanımlı aralık 0 ile 16777215 arasındadır.
    INT or INTEGER
    Normal büyüklükteki integer değerler içindir.
    Signed tanımlı durumda iken alabileceği değerler  2147483648 ile  2147483647 arasındadır.Unsigned tanımlı aralık 0 ile 4294967295 arasındadır.
    BIGINT
    Büyük integer değerler içindir.
    The signed range is 9223372036854775808 to 9223372036854775807. The unsigned range is 0 to 18446744073709551615
    FLOAT
    Küçük (single-precision) floating-point değerler içindir.Unsigned olarak çalışmazlar.
    Değer aralıkları;  3.402823466E+38 ile 1.175494351E-38, 0 arası ve 1.175494351E-38 ile 3.402823466E+38 arasındadır. Eğer sayının onluk kısmı(virgül öncesi) atanmamışsa ya da 24 basamaktan küçük  veya eşitse <= 24 bu bir single-precision floating point değeridir. (single-precision / floating-point)
    DOUBLE,
    DOUBLE PRECISION,
    REAL
    A normal-size (double-precision) floating-point number. Cannot be unsigned
    Değer aralıkları; -1.7976931348623157E+308 ile -2.2250738585072014E-308, 0 arası ve 2.2250738585072014E-308 ile 1.7976931348623157E+308 arası. Eğer sayının onluk kısmı(virgül öncesi) atanmamışsa ya da onluk basamak sayısı 25 ve 53 arasında ya da 25 veya 53’e eşitse bu bir double-precision floating point değeridir.
    DATE
    Tarih
    Desteklenen aralık  1000-01-01 ile 9999-12-31 arasıdır. MySQL tarihleri YYYY-AA-GG biçiminde gösterir.
    DATETIME
    Tarih ve zaman kombinasyonu
    Desteklenen aralık 1000-01-01 00:00:00 ile 9999-12-31 23:59:59’ arasıdır. MySQL DATETIME değerlerini YYYY-MM-DD HH:MM:SS biçiminde gösterir.
    TIMESTAMP
    Zaman damgasıı
    Desteklenen aralık 1970-01-01 00:00:00 ile 2037 yılında herhangi bir zaman arasındadır.MySQL TIMESTAMP değerlerini YYYYAAGGSaSaDkDkSnSn, YYAAGGSaSaDkDkSnSn, YYYYAAGG veya YYGGAA biçimlerinde gösterir.TIMESTAMP insert ve update işlemlerinde kullanışlıdır çünkü değer verilmesi bile işlemin yapıldığı andaki tarih zaman bilgisinin timestamp karşılığı otomatik olarak kaydedilir.
    TIME
    Zaman
    Desteklenen aralık  -838:59:59 ile 838:59:59’ arasındadır. MySQL TIME değerlerini HH:MM:SS biçiminde gösterir.
    YEAR
    2 ya da 4 basamaklı yıl bilgisi (öntanımlı 4 basamaklı)
    4 basamaklı yıl bilgisinde değer aralığı 1901 ile 2155 arasındadır. 2 basamaklı yıl bilgisinde değer aralığı 1970-2069 için 70 ile 69 arasındadır.MySQL YEAR değerlerini YYYY formatında gösterir.
    CHAR
    A fixed-length string that is always right-padded with spaces to the specified length when stored
    Maksimum 255 karakter barındırabilir. Tekrar eden boşluklar değer alındığı zaman silinir.Öntanımlı karakter seti BINARY tanımlanmamışsa CHAR değerler büyük-küçük harf duyarlılığı olmadan sıralanır veya karşılaştırılırlar.
    VARCHAR
    A variable-length string. Note: Trailing spaces are removed when the value is stored (this differs from the ANSI SQL specification)
    Maksimum 255 karakter barındırabilir. VARCHAR değerleri BINARY anahtar sözcüğü verilmediği takdirde büyük-küçük harf duyarlılığında sıralanır veya karşılaştırılırlar.
    TINYBLOB,
    TINYTEXT
    255 karakterli bir BLOB ya da TEXT verisi
    BLOB,
    TEXT
    65535 karakterli bir BLOB ya da TEXT verisi
    MEDIUMBLOB,
    MEDIUMTEXT
    16777215 karakterli bir BLOB ya da TEXT verisi
    LONGBLOB,
    LONGTEXT
    4294967295 karakterli bir BLOB ya da TEXT verisi
    ENUM
    An enumeration
    Değer listesinden seçilebilecek her biri maksimum 65535 karakterli string değerler tutabilir.
    SET
    A set
    Maksimum 64 elemanlı string değerler kümesi.
  • 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:

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

    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.

    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. 

  • 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.

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

    Kullanımı ise şu şekilde olacak

    Bu şekilde aynı sonuçları daha performanslı alabilirsiniz.
    Kullandığımız VIEW‘ı silmek içinde şu kodu kullanabiliriz.
  • 12-MYSQL PARTITION özelliğini kullanabilirsiniz
  • MYSQL PARTITION özelliği ne işe yarar derseniz şu şekilde açıklayalım.Mesela elinizde 1 milyon satır veri var diyelim ve bu verilerin yıllar bazında oluşturulma tarihleri olsun.Biz sadece 2013 yılına ait verileri istediğimizde normalde 1 milyon veri arasından 2013 yılına ait verileri getirir.Ancak MYSQL PARTITION özelliğini kullanırsak yıllara göre sıralayıp 2013 yılında 100 bin kayıt varsa sadece 100 bin kayıt arasından SELECT yaparız.Bu da performans ve hız açısından iyidir.Ancak bu özelliği kullanırken çok iyi bir hakimiyetinizin olması gerekir.

Yazar Hakkında

6 Comments

  1. hocam merhabalar;

    çok faydalı bir makale yazmışsınız teşekkür ediyorum. mysql view kullanıyorum fakat, primary id si belirtilmemiş diyor , view oldugu için primary alan zaten belirtemiyoruz viewlar datalar arttıkca çok hantal bir hal alıyor. bunun için ne önerirsiniz?

  2. Hocam bilgilendirme için teşekkür ederim güzel bir doküman hazırlamışınız.

  3. Çok iyi bir yazı olmuş usta, teşekkür etmeden geçemedim…

  4. Hocam where şartı kullanırken dikkat edilmesi gerekenler derken sıra ne şekilde olmalı. Where şartında sıranın bir önemi yok diye biliyorum. Bir örnek sql cümlesi ile bunu anlatır mısınız?

  5. Gerçekten çok faydalı bir yazı. Allah razı olsun elinize sağlık.

  6. Faydalı bir makale yazmışsınız. Elinize sağlık.

Leave a Reply

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

Close