Konuyu görüntüle
IUCODERS FORUM > Programlama > Veritabanları > update koşullarının performans üzerindeki etkisi
Yazar
clairvoyant


avatar
Antalya
Kayıt: 05.05.2006
09.12.2007-01:07 #32497
MySQL motoru için;

Çok sayıda kayıt içeren bir tablo üzerindeki bir alanın değerini bütün kayıtlarda aynı yapmak için, bir kayıttaki alanın önceki değerinin kontrol edilmesinin performans üzerindeki etkisi hakkında bir fikriniz var mı?

Örneğin:

UPDATE `players` SET `points`=0;
UPDATE `players` SET `points`=0 WHERE `points`!=0;

Bu iki sorgu arasında performans farkı var mıdır sizce? Ben çok düşündüm ama net birşey çıkaramadım. İlk sorguda değiştirme işlemini bütün satırlara uyguluyor. Fakat var olan değer ile yeni değeri karşılaştırdıktan sonra mı değiştiriyor? Eğer böyle bir karşılştırma varsa ikinci sorgudaki gibi bir kriter kullanmak performans açısından mantıksız olur. Eğer değiştirme işlemi sırasında bu kontrol yapılmadan var olan veri yerine yeni veri yazılıyor ise bu sefer de ikinci sorgudaki koşulu yazmak performansı arttırır gibi geliyor.

Kısacası MySQL motorunda güncelleme işlemi sırasında var olan verinin üzerine yazılmadan önce önce bu veri ile yeni veriyi karşılaştırıp karşılaştırmadığı konusunda bir fikriniz var mı?

Az sayıda kayıt için bunun fazla önemi olmaz, fakat binlerce kayıt içerisinde bu koşulu sağlamayan kayıt sayısı çok fazla ise, hangi sorgunun daha hızlı çalışacağı konusu önem kazanır diye düşünüyorum.

Fikirleriniz nelerdir?





Let`s make this world a better place to live !

Yazar
orhan


avatar
istanbul
admin
Kayıt: 17.11.2005
09.12.2007-01:12 #32499
execution plana bakmak lazım
indexlerin yada tablo yapına göre değişir. Execution Plana bakıp incelmek lazım.

http://dev.mysql.com/doc/refman/5.0/en/explain.html





N/A
Yazar
kafacan


avatar
istanbul
Kayıt: 22.01.2006
09.12.2007-01:48 #32501
ilk sorguda ne olursa olsun karşilaştırma yapmadan direk update yapar diğerinde ise sadece 0 olmayan listeleyip onlari yaptiği için çok daha kisa suede yapmasi gerekir diye dusunuyorum ikincisi bana daha mantıkluı geliyor genlede onu kullaniyorum

where isnull (column_name) and column_name!=0 kullanirsan boş ve 0 olmayanlari index er ve onlari değiştiriri ve diğerinden çok hızlı olur wink





Yazar
clairvoyant


avatar
Antalya
Kayıt: 05.05.2006
10.12.2007-15:20 #32559
Şu da var; koşul olsa da olmasa da bütün kayıtların tek tek gezilmesi gerekir. Değiştirme işlemi yapmadan önce sistem kendisi bir kontrol yaparsa, aynı olan veriyi değiştirmeyerek yazma işlemini azaltabilir diye düşünüyorum. Böyle bir durumda SQL içinde kontrol yapmak işlem sayısını arttırabilir. Ama hepsinden önce diske yazma işleminin detayları hakkında bilgi sahibi olmak gerekir. Verileri belleğe aldıktan sonra sadece kriterlere uyan veriler değiştirilip, yazma işlemi sadece bu verilerin diskteki adreslerinde yapılıyorsa SQL içinde kontrol yapmak avantajlı gibi görünebilir. Fakat diske yazma işleminden tasarruf etmek için sistem bunu kendiliğinden de yapabilir.
Meraklıyım böyle konulara. biggrin





Let`s make this world a better place to live !

Yazar
orhan


avatar
istanbul
admin
Kayıt: 17.11.2005
10.12.2007-17:30 #32561
execution plan da yazmış olduğun sql in ne kadar read yaptığını ne kadar cpu kullandığını ne kadar döngü yaptığını görebilirsin.





N/A
Yazar
clairvoyant


avatar
Antalya
Kayıt: 05.05.2006
10.12.2007-18:54 #32566
Execution planı görebileceğim bir yol bulamadım. Bunu komutlarla görebilmek mümkün mü? EXPLAIN komutundan faydalanarak bu konuda bir bilgi alamadım (ya da ben beceremedim :D). Ama yaptığım denemelerden aldığım sonuçlara göre MySQL motoru bu konuda kendisini optimize edebiliyor. Her iki sorgu denemesi de çok az zaman farkları ile geri dönüyor. Bu sonuçlar sorgunun hemen öncesinde optimize edilmiş tablo için.

mysql> SHOW PROFILES;
+----------+------------+----------------------------------------------------------+
| Query_ID | Duration   | Query                                                    |
+----------+------------+----------------------------------------------------------+
|        1 | 2.12988675 | UPDATE `player` SET `points` = 0                       | 
|        2 | 2.13139975 | UPDATE `player` SET `points` = 0 WHERE `points` != 0 | 
+----------+------------+----------------------------------------------------------+
2 rows in set (0.00 sec)

mysql> SHOW PROFILE FOR QUERY 1;
+----------------------+-----------+
| Status               | Duration  |
+----------------------+-----------+
| (initialization)     | 0.0000022 | 
| checking permissions | 0.0000085 | 
| Opening tables       | 0.0000142 | 
| System lock          | 0.0000065 | 
| Table lock           | 0.0000055 | 
| init                 | 0.0000287 | 
| Updating             | 2.1286532 | 
| end                  | 0.0004047 | 
| query end            | 0.000014  | 
| freeing items        | 0.0007297 | 
| closing tables       | 0.0000165 | 
| logging slow query   | 0.0000027 | 
+----------------------+-----------+
12 rows in set (0.02 sec)

mysql> SHOW PROFILE FOR QUERY 2;
+----------------------+-----------+
| Status               | Duration  |
+----------------------+-----------+
| (initialization)     | 0.0000759 | 
| checking permissions | 0.0000102 | 
| Opening tables       | 0.000016  | 
| System lock          | 0.0000062 | 
| Table lock           | 0.0000057 | 
| init                 | 0.000052  | 
| Updating             | 2.130908  | 
| end                  | 0.0002887 | 
| query end            | 0.0000085 | 
| freeing items        | 0.0000175 | 
| closing tables       | 0.0000085 | 
| logging slow query   | 0.0000022 | 
+----------------------+-----------+
12 rows in set (0.00 sec)





İlgisini çekenler için şu adreste güzel makaleler var.

http://forge.mysql.com/wiki/MySQL_Internals





Let`s make this world a better place to live !

Del.icio.us
Digg
Facebook
Furl
Google
Blink
Simpy
Spurl
Y! MyWeb