Doğru Cevap
-
Merhaba,
Veritabanında performas istiyorsanız bunu açma-kapama gibi yerlerde aramayın.
Performans'ın belkide tek şartı INDEX ve WHERE koşulunuzun analizinden geçer.
Şöyle ki, 70 milyon satırlık bir tablonuzda TCKIMLIK, ADISOYADI, SEHIR, ILCE, MAHALLE gibi alanlar olsun.
Tablonuzun SADECE tckimlikno'ya göre indexli olduğunu varsayalım.
select * from mytable where TCKIMLIKNO="12345678901"
şeklindeki bir kod, 1 milisaniyenin de altında bir hızla çalışır. Kayıt sayınız 7 milyar da olsa bu değişmez.
Bir de şu koda bakalım:
Çankırı'nın, Kurşunlu İlçesinin, Yeşilöz köyüne kayıtlı kişi sayısı sadece 15 kişi olsun.
select * from mytable where SEHIR="cankiri" and ILCE="kusunlu" and KOY="yesiloz"
Şeklinde yazacağınız sorgu 3 DAKİKA kadar çalışabiir ve bu sırada tüm sisteminiz kitlenecektir.
Tek yapmanız gereken, mümkün olabildiğince WHERE şartında kullandığınız GEREKLİ tüm sahalara INDEX vermek. Hepsi bu kadar !
Bu 3 sahaya index verdikten sonra yukarıdaki sorgu DAKİKALAR boyunca çalışmaz, tıpkı tckimlikno ile arama yapar gibi milisaniyenin altında bir sürede sonuçlanır.
Her şey bu kadar basit değil elbet, ama başlama noktanız bu olmalı.
Selamlar,
Nuri Akman
Cevaplar
-
ilk olarak dikkat edilmesi gereken husus her select işlemi için bağlantı açıp kapatmamak. kod sayfasının en başında açılan bağlantıyı en atta kapatırsanız bu performası çok arttırır. Bir diğeri select sorgularını ihtiyaca göre ayarlamak. örneğin sorgu yapılacak tabloda 50 alan var diyelim. size tamamı lazım olmaya bilir. bu durumda ihtiyacınız olan alanlar 5 ise ve siz veritabanından select * from şeklinde sorgu yaparsanız gereksiz veri çekimi yapacağınızdan bu işlem gereksiz yere sistem performansını düşürecektir. Diğer bir husus php ile kullandığınız veritabanı türü. PHP ile en uyumlu ve hızlı çalışan veritabanı MySQL dir. Bunu kullanmanızı tavsiye ederim. Sayfanın en altına sayfanın yüklenme süresini yazdırırsanız bu adımları yapmadan ve yaptıktan sonraki farkı net olarak görebilirsiniz.
-
mehmetali
teşekkürler
ufak bi araştırma sonucunda şey varmış
mysql_free_result bu da işe yararmış12 yıl önce yazılmış
-
-
mysql_free_result önemli, ama bunun için öncelikle bir database wrapper kullanmanızı tavsiye ederim, başka faydalarını da görürsünüz. Result'ları da kendi free eder...
En önemli dikkat edilmesi gereken iç içe sorgulardan kaçınmak:
$users = $db->fetchAll("select * from users limit 30"); foreach($users as $user) { echo $user['name'] . " kullanıcısının makaleleri: <br>"; $articles = $db->fetchAll("select * from articles where user_id=?", $user['id']); foreach($articles as $article) { echo $article['title']." <br>"; } }
Burada 30 kere "select * from articles" sorgusu çalıştırılır bu da özellikle yüksek yük altında veritabanını bayıltır.
Yine yüksek yük altında select * yerine mümkün olduğunca select id, name ... gibi sadece gerekli olan alanları çağırmak daha az RAM işgal eder.
Bağlantıyı kapatmak çok da kritik bir konu değil çünkü php'nin işini bitirince açık kalan bağlantıları otomatik kapatır zaten. Ama sadece bir kere açtığınızdan emin olmanız önemli. Persistent connection önermiyoruz...
Oracle söz konusu olduğunda, Oracle 11'den önce PHP için bir connection pooling mevcut değil, bu da bir yavaşlığa neden oluyor. TNS ayarlarından DEDICATED ayarı ile çözüm üretilebiliyor ama bu tamamen ayrı bir konu, detaylarına girmeyeyim.
PHP haricinde genel olarak düşünürsek tabii çok önemli konulardan biri index'lerin doğru olarak tanımlanması ve sorguların bu indexleri doğru kullandığından emin olmak.
Onun dışında sql'lerde veritabanının doğasına uygun optimizasyonlar yapılmalı. Mesela MySQL için SQL_CALC_FOUND_ROWS diye bir keyword var, Oracle için ise subquery'ler oldukça hızlı çalışabildiği için select count(*) from (select ....) gibi birşey daha hızlı çalışabiliyor.
Performans optimizasyonunda hangi veritabanı olursa olsun, her zaman için yük altında sistem nerede sıkışıyor tespit edip gerekli ayarları yaparak adım adım bu sıkışmaları (bottleneck) teker teker elimine etmeniz gerekir. Bunun için her veritabanına özgün muhtelif trickler vardır, mesela MySQL için mysql_slow_log diye bir şey var, onu takip etmeniz ve parametreleri kontrol etmeniz gerek. Oracle için zaten kendisine ait detaylı bir admin tool'u var...-
bensedat18
hocam bahsettiğiniz iç içe sorgunun tek sorguda yapılabilir halini yazabilir misiniz rica etsem?9 yıl önce yazılmış -
madpoet
En basit çözüm, ilk sorgudan user_id'leri çekip article'ları user_id in (...) şeklinde alabilirsiniz. 2 query'de biter iş. Join ile tek sorguya indirmek de mümkün ama pek mantıklı değil bana göre, hem veritabanından çektiğiniz row size büyüyecek hem de data'yı insan gibi yapmak için ekstra birşeyler yapmanız gerekecek.
İhtiyaca ve data'nın yapısına göre farklı yöntemler kullanılabilir, bu işi veritabanına değil bir key/value storage'a devretmek (bkz. redis) mesela...9 yıl önce yazılmış -
bensedat18
teşekkür ederim, merakımı giderdiniz.9 yıl önce yazılmış
-
-
ikinizede ayrı ayrı tşk. ederim
çok işime yaradı index yapıları-
ireaf
Selam arkadaşlar. Bu konuda sayenizde birşeyler öğrendim. Herkese çok teşekkürler.12 yıl önce yazılmış
-