MySQL İpuçları — Detaylı Anlatım 1
UO-Developer.com — Sphere + MySQL performans, doğru sorgu yazımıBu rehber, Sphere shard'ında MySQL kullanırken makinenizi gereksiz yükten kurtaracak pratik ipuçlarını anlatır. Ufak görünen detaylar birikince ciddi performans farkı yaratır.
Konu: SELECT, COUNT, INSERT, SUM optimizasyonu | Seviye: Orta – İleri
Ön koşul: MySQL Kurulumu | MySQL'den Yararlanma
İlgili: MySQL İpuçları | MySQL Komutları | Sphere, MySQL ve PHP
db.execute temelleri: projedeki Sphere MySQL db.execute Rehberi
İçindekiler
- SELECT * hatası
- num_rows yerine COUNT
- INSERT doğru kullanımı
- SUM ile toplam puan
- İlerleyen konular
- Özet
1. SELECT * — Yanlış Sorgu Alışkanlığı
Varsayalım MySQL'den oyuncu isimlerini çekip listeleyeceksiniz. Veritabanında şu alanlar var:
charName, charKarma, charFame, charKill, charUid, charGold, insertDate
Yanlış sorgu:
SELECT * FROM playerListBu sorgu tüm kolonları döndürür — charName, charKarma, charFame, charKill, charUid, charGold, insertDate — oysa siz yalnızca birkaçına ihtiyaç duyuyorsunuz.
Örnek: Listede yalnızca isim gösterecek, yanına buton için charUid kullanacaksınız.
Doğru sorgu:
SELECT charName, charUid FROM playerListNeden önemli? 40 oyuncu listelerken her satırda yaklaşık 3 KB veri çekmek toplamda ~120 KB RAM demektir. Yalnızca 2 alan alsaydınız bu ~10 KB'a düşerdi.
Sphere'de:
db.query "SELECT charName, charUid FROM playerList"
// Sonuç: <db.row.0.charName> , <db.row.0.charUid>Kural: İhtiyacınız olmayan kolonu SELECT'e eklemeyin — yıldız kullanmayın.
2. num_rows Yerine COUNT
Toplam kayıt sayısını almak için tüm satırları çekip num_rows ile saymak yaygın ama verimsiz bir hatadır.
Yanlış — PHP tarafı:
SELECT id FROM playerList
// ardından mysql_num_rows($query)Yanlış — Sphere tarafı:
Tüm id satırlarını db.query ile çekip döngüde saymak — gereksiz.
Doğru:
SELECT COUNT(id) AS sayi FROM playerListPHP:
$row = mysql_fetch_assoc($query);
$toplam = $row['sayi'];Sphere:
db.query "SELECT COUNT(id) AS sayi FROM playerList"
// Sonuç: <db.row.0.sayi>MySQL tek seferde sayar; siz ikinci kez saymazsınız — hem disk hem RAM yükü azalır.
3. INSERT — Doğru Kullanım
Yaygın hatalı INSERT örneği — tüm kolonları VALUES ile doldurmak, NULL id, serv.time ile tarih yazmak:
INSERT INTO playerList VALUES (NULL,'<name>','<karma>','<fame>','<kills>','<uid>','<gold>','<serv.time>')Sorunlar:
- id AUTO_INCREMENT ise NULL yazmaya gerek yok — MySQL yine parse eder
- Tarih için TIMESTAMP / DATETIME + CURRENT_TIMESTAMP kullanılabilir — insertDate kolonuna elle değer yazmayın
- Hangi değerin hangi kolona gittiği okunaksız — kolon sırası değişince veri kayması riski
Doğru INSERT — kolon adları açık:
INSERT INTO playerList (charName, charKarma, charFame, charKill, charUid, charGold)
VALUES ('<name>', '<karma>', '<fame>', '<kills>', '<uid>', '<gold>')Sphere:
db.execute "INSERT INTO playerList (charName,charKarma,charFame,charKill,charUid,charGold) VALUES ('<name>','<karma>','<fame>','<kills>','<uid>','<gold>')"Kolon sırası önemli mi? INSERT'te kolon listesi ile VALUES sırası eşleşmeli; listedeki kolon sırasını değiştirseniz VALUES sırasını da ona göre yazın — veriler yanlış kolona gitmez, yalnızca eşleştirmeyi siz kontrol edersiniz.
Örnek — farklı kolon sırası, doğru eşleştirme:
INSERT INTO playerList (charGold, charKarma, charFame, charName, charKill, charUid)
VALUES ('<gold>', '<karma>', '<fame>', '<name>', '<kills>', '<uid>')Veriler doğru kolonlara gider; charName hâlâ charName kolonuna yazılır.
Tarih kolonu için tablo tasarımı:
insertDate TIMESTAMP DEFAULT CURRENT_TIMESTAMPBöylece INSERT'te insertDate yazmadan MySQL otomatik doldurur.
4. SUM — Döngü Yerine Tek Sorgu
Bir oyuncunun sürekli artan puanını toplamak için her kill'de INSERT yapıp ardından While / For ile satır satır toplamak yaygın ama gereksiz bir yöntemdir. UPDATE ile tek satır güncellemek genelde daha doğrudur — yine de mevcut yapınız çok satırlı INSERT ise toplamı SQL'de alın.
Doğru toplama sorgusu:
SELECT SUM(playerPoint) AS point FROM playerPoints WHERE player = '<uid>'Sphere'de sonuç:
db.query "SELECT SUM(playerPoint) AS point FROM playerPoints WHERE player = '<uid>'"
// Çıktı: <db.row.0.point>UID verdiğiniz oyuncunun tüm puanları tek sorguda toplanır. While veya For döngüsüyle PHP/Sphere tarafında toplamaya gerek kalmaz.
5. İlerleyen Konularda Anlatılacaklar
Bu serinin devamında planlanan başlıklar:
- GROUP BY kullanımı
- GROUP_CONCAT kullanımı
- LEFT JOIN — iki tabloyu eşleştirme — örnek: playerList ile playerPoints
- LEFT fonksiyonu
- MID fonksiyonu
Beş konu tamamlandıktan sonra bir sonraki bölümde ek anlatımlar yer alacaktır.
6. Özet
- SELECT * kullanmayın — yalnızca ihtiyacınız olan kolonları yazın
- Kayıt sayısı için COUNT — tüm satırları çekip saymayın
- INSERT — kolon adlarını açık yazın; TIMESTAMP ile tarihi otomatik bırakın
- Toplam için SUM — döngü yerine tek SQL sorgusu
- Sphere: SELECT → db.query | INSERT/UPDATE/DELETE → db.execute
Forum: Sphere MySQL Hakkında

