Merhaba arkadaşlar bildiğiniz gibi bu blog’umda genelde pek birşey yazmıyorum ama son günlerde oldukça fazla yazı / yorum / paylaşım görüyorum PHP YAVAŞ gibi söylemler dolanıyor şimdi gelin bunu biraz analiz edelim acaba yavaşmı ? yoksa biz’mi hatalar yapıyoruz ?
Öncelikle standart olarak dillere göre hız sıralamasını inceleyecek olursak PHP‘den hızlı dillerin olduğunu göre biliyoruz. ama bu PHP çok yavaş anlamına gelmiyor… eğer böyle olsa’idi onca büyük php sistemler nasıl iyi performans sağlıya bilir diki ?
Neyse fazla uzatmadan günümüzde yapılan en çok hatalara göz atalım.
Veritabanı işlemlerinin Ezbere yapılması
Derken neyi kastediyor ola bileceğimi bazılarınızın fikri vardır. evet düşündüğünüz gibi yanlış değer kullanımı.
Örneğin basit bir işlemimiz var Cinsiyet ‘leri veritabanında 0 ve 1 olarak tutuyoruz ama çoğu kişi gelişe güzel yaptığı için bunları oluştururken veri tipini şöyle belirliyor.
hmm bu bir sayı ? aynen aynen sayı öyle ise int
işte bu yanlış yukarıda’da dediğimiz örnek için int kullanmak mantıksızdır neden’mi ?
int değerler 4 Bayt veri tutar ama bizim işlemimiz için böyle geniş alana ihtiyacımız yok’ki sadece 0 ve 1 tutacağız.
öyle ise bizim için en mantıklı seçim tinyint ‘dır çünkü 1 bayt yer kaplar aradaki farka bakın tam 4 katı böyle gelişi güzel hesap’ta fark göremeye bilirsiniz. ama büyük düşünün.
100.000 sorgu var ve 1 saniyede bir oluyor. öyle ise bu 1 saniyede 400.000 bayt ram tüketimi demektir. ama diğer türlü ise 100.000 bayt ‘a bu işlemi yaptıra biliriz.
Not : unutmamız gereken şeyler’den biri ise tinyint ‘ın 0-255 arası sayıları desteklediğidir 256 olamaz !
En basit örnek yukarıdaki şekilde olacağını düşünüyorum diğer veri tiplerine geçicek olursak onun için şöyle bir tablo hazırladım uygun veri tipini seçmenizde yardımcı olur arkadaşlar.
En çok hata yapılan kısımlardan biri ise sorgularda UPDATE kısmı yani güncelleme kısmıdır arkadaşlar.
Misal bir örnek düşünelim ;
Yazı adında bir stunum’da savas yazıyor ben buna can eklemek istiyorum. bir çok arkadaş bu işlemi şu şekilde yapıyor.
ÖNCE VERİYİ ÇEKİYOR
SONRA VERİYE EKLİYOR
SONRA VERİYİ YAZDIRIYOR
Bakın 3 aşama yazması bile zor : P peki bunun gibi bir çok şeyin çok kolay alternatifleri olduğunu biliyor’muydunuz ?
Misal yukarıdaki işlemi sadece alttaki şekilde’de yapa biliriz.
1 |
update ornek set yazi=concat(yazi, ',can') |
Yukarıdaki işlemi böyle yapmak daha kolay değilmi ? :) yani veriyi çekmeden hiç bir işlem yaptırmadan en basit yolla yaptık buda bizim performansımız için büyük bir avantaj arkadaşlar.
Başka neler var diyecek olursak.
Misal üye giriş uygulamalarında klasik bir yapı vardır girilen kullanıcı adı ile şifre veritabanında sorgulanır ve sonuçlar saydırılır eğer 0’dan büyük ise var demektir peki bunu daha kolay yapamazmıyız ?
Tabiki yaparız : )
Şimdi iki türlüde örnek yapalım
1 |
SELECT COUNT(*) * from users where username='savas' and sifre='123456' |
Yukarıda yaptığımız işlem ile saydırıp sonucu elde edebiliriz ama daha kolay bir yöntem mevcut oda şu şekilde
1 |
SELECT EXISTS(SELECT * FROM uyeler WHERE id=1 and sifre=123456) |
EXISTS ifadesi bir nevi sonuçlar veya sonuç gibi düşüne biliriz yani kurala göre var yada yok der tabi bunları var veya yok olarak demez 0 ve 1 olarak der yukarıdaki kullanım daha makul ve kolay kullanım türlerinden biridir.
Gereksiz stun ( veri ) çekme hatası
yazının başlarında veri tipleri hakkında bilgi vermiştim şimdi basit bir tablomuz var sayalım
Bu şu şekilde olsun ve adı kayitlar olsun.
id – ad – soyad – mesajı
buradaki mesaj kısmı text biçiminde olsun. yani bu 64 kilo bayt ( KB ) bir kullanım demek oluyor ( Yanlış hatırlıyor ola bilirim )
Bizim yapacağımız işlem ise sadece ad ve soyadı almak
Bunu şu şekilde gelişi güzel yapa bilirsiniz.
1 |
select * form kayitlar |
bu şekilde sorgu yapa biliriz ama burada boş yere MESAJ ve İD kısımlarını’da alıyoruz ve Daha çok iş yaptırıyoruz şöyle düşünün 1 Litre suya ihtiyacınız var ama siz gidip 1 damacana alıyorsunuz ve gelip 19 litresini döküyorsunuz
bu mantıksız bir şeydir öyle değilmi ? Mantıklıdır diyen varmıdır acaba ? bence değil. yukarıdaki işlemde buna benziyor boş yere taşıyoruz ve sonunda silip yok ediyoruz işimize yaramıyor niye yük yapalım’ki ?
onun yerine sadece işimize lazım olan kısımları ala biliriz yani şu şekilde
1 |
select ad,soyad form kayitlar |
Böylece 64 KB ‘lik verileri çekmekten kurtulduk 100.000 veri olsa bu 6.400.00 KB veri yapar Aşşağı yukarı 625 MB yapıcaktır.
Belki tek işlemlerde fark olmaya bilir ama sayı çoğaldıkça farklar daha ne anlaşılır olduğunu göre biliyoruz.
Döngü içinde İD Almak ve Bunu döngü biçiminde kullanmak
Döngü içinde id kullanmak yerine daha doğrusu dizidekilere göre döngü döndürmek mantıksız hareketlerden biridir örnek olarak bir dizimiz olduğunu var sayalım
( array falan demiyorum teorik olarak anlatıyorum )
dizi adımız idler ve içeriği 1 2 3 4 5 6 şeklinde benim yapmak istediğim id’si bu idler içinde olan verileri çekmek
düz mantık ile gidecek olursak
basit bir foreach döngüsü ile veya for döngüsü ile $idler[$i] biçiminde her döngü döndükçe $i ‘i artırarak yapa bilirsiniz veya daha kısa yöntem olarak diziyi , (virgül) bölerek’de bu işlemi yapa bilirsiniz yani misal örnek sorgumuzu elle yazıcak isek şöyle yazmamız gerekir yani ulaşmamız gereken sonuç budur.
1 |
SELECT * FROM kayitlar where id in(1,2,3,4,5,6) |
veya dizi ile tek tek id=$i şeklinde sorgulaya biliriz sonuç aynı olur ama PERFORMANS aynı olmayacaktır örnek olarak yukarıdaki diziyi implode ile bölerek daha doğrusu , ( virgül ) parçalayarak’ta bu işlemi yapa biliriz hemen örnek yapalım
1 |
SELECT * FROM kayitlar where id IN(".implode(',',$idler).') |
Yukarıdaki şekilde tüm diziyi , ( virgül ) ‘e ayırarak yazdırmış olduk böylece döngü açmadan sonuca ulaştık ve her seferinde sorgu yapma zahmetinden’de kurtulduk
Yazının devamı gelicektir…