Ruby ile KyotoCabinet – 3

Merhabalar,

Bir önceki yazımızda Ruby üzerinden KyotoCabinet’e 1.000.000 (1 milyon) veri giriÅŸini çok kısa bir sürede tamamlamıştık. Daha sonra içime bir kurt düştü, acaba mysql’de durum nasıldı? Yani aynı koÅŸullar altında mysql veri tabanına 1.000.000 kayıdı kaç sn içerisinde yazabilecektim?

Makinanın özelliklerini bir önceki yazımızda vermiştim.

Bu iÅŸlemin testi için öncelikle kendimize oldukça hızlı olduÄŸuna inandığım, KyotoCabinet’in Ruby arabiriminde olduÄŸu gibi C dili ile yazılmış MySQL/Ruby bir arabirim kütüphanesi buldum ve 2.8.2 versiyonunu kurdum. Bununla beraber MySQLClient versiyonunun 5.1.41 olduÄŸunu söylemeliyim.

Daha sonra key, value tutacağımız bir veri tabanı oluşturdum. Öncelikle MyISAM motorunu kullanan bir tablo oluşturdum ve testlerimi bu tablo üzerinde yaptım.

CREATE TABLE `kyoto_cabinet`.`simple_table` (
  `key` CHAR(12) UNICODE NOT NULL,
  `value` CHAR(12) UNICODE NOT NULL,
  PRIMARY KEY (`key`)
)
ENGINE = MyISAM
CHARACTER SET utf8 COLLATE utf8_turkish_ci;

Bu tablo için aşağıdaki kod parçasını uyguladım;

require "mysql"

begin
  dbh = Mysql.real_connect("localhost", "kyoto_cabinet", "kyoto_cabinet", "kyoto_cabinet")
  dbh.autocommit(false)
  st = dbh.prepare("insert into simple_table values (?,?)")
 
  start_number = 905420000001
  start_time = Time.now
  puts "sira;gecen_sure;toplam_gecen_sure"
  100.times { |index|
    first_loop_start_time = Time.now
    10000.times {
      start_number += 1
      st.execute(start_number, start_number)
    }
    dbh.commit
    loop_elapsed = Time.now.to_f - first_loop_start_time.to_f
    total_elapsed = Time.now.to_f - start_time.to_f
    puts index.to_s + ";" + loop_elapsed.to_s + ";" + total_elapsed.to_s
  }
  puts "1.000.000 kayit eklenmistir. Toplam süre: " + (Time.now.to_f - start_time.to_f).to_s  
rescue Mysql::Error => e
  puts "Error code: #{e.errno}"
  puts "Error message: #{e.error}"
  puts "Error SQLSTATE: #{e.sqlstate}" if e.respond_to?("sqlstate")
ensure
  # disconnect from server
  dbh.close if dbh
end

* Hemen belirtmekte fayda var, bu kod parçasının boşta (insert olmadan) çalışması sırasında her 10.000 kayıt için ortalama ~0.014 sn ve toplamda ~1.43 sn harcanmıştır.

Sonuç pek de beklediÄŸimiz gibi deÄŸil; ortalama her 10000’lik kayıdı ~1.19 sn’de iÅŸleyebildik. Toplamda ~119 sn harcamış olduk. Bu iÅŸte bir terslik var sanki, her ne kadar MySql sisteminin hızlı olması için CHAR veri tipini kullansam da Ruby’de kullandığım veri tipi numeric, bu nedenle Mysql üzerindeki tablo tasarımını aÅŸağıda gösterildiÄŸi ÅŸekilde deÄŸiÅŸtirdim.

CREATE TABLE `kyoto_cabinet`.`simple_table` (
  `key` BIGINT ,
  `value` BIGINT ,
  PRIMARY KEY (`key`)
)
ENGINE = MyISAM;

Ve tekrar çalıştırdım. Sonuç; ortalama olarak her 10000’lik kayıdı ~0.78 sn’de iÅŸleyebildik. Toplamda ~78 sn harcamış olduk. Bu ÅŸekilde %35’lik iyileÅŸme kaydetmiÅŸ olduk fakat bu rakamlar kyotoCabinet rakamlarına göre oldukça yüksek (yaklaşık 10 kat kadar).

Fakat bu sonuçta benim için yetmedi. MySql’in daha iyileÅŸtirilebileceÄŸini düşünüyorum. Bu nedenle aÅŸağıdaki gibi bir tablo oluÅŸturdum;

CREATE TABLE `kyoto_cabinet`.`simple_table` (
  `key` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
  `value` BIGINT UNSIGNED,
  PRIMARY KEY (`key`)
)
ENGINE = MyISAM;

Testi tekrar çalıştırdım, sonuçta bir önceki AUTO_INCREMENT’siz haline göre pek bir deÄŸiÅŸim olmadı ama hazır testi yapmışım, sonuçların arasından çıkarmak istemedim :)

Daha sonra MyISAM yerine InnoDB kullanmayı denedim;

CREATE TABLE `kyoto_cabinet`.`simple_table` (
  `key` BIGINT ,
  `value` BIGINT ,
  PRIMARY KEY (`key`)
)
ENGINE = InnoDB;

Sonuç; ortalama olarak her 10000’lik kayıdı ~0.81 sn’de iÅŸleyebildik. Toplamda ~80.1 sn harcamış olduk. DiÄŸerlerinden çok farklı deÄŸil.

Ve son olarak InnoDB veya MyISAM yerine MEMORY motorunu kullandım.

CREATE TABLE `kyoto_cabinet`.`simple_table` (
  `key` BIGINT ,
  `value` BIGINT ,
  PRIMARY KEY (`key`)
)
ENGINE = MEMORY;

Sonuç; ortalama olarak her 10000’lik kayıdı 0.57 sn’de iÅŸleyebildik. Fakat test yarıda kaldı. 600.000 kayıttan sonra “table is full” hatası aldık. Bu hatayı alana kadar 35 sn. geçmiÅŸti.

Ve son olarak, her 10000 kayit kümesi için ortalama oluşan sonuçlar aşağıdadır;

KyotoCabinet için;
BoÅŸta: 0.0140892158855091
Toplam: 0.0746499228477478
Gerçek: 0.0605607069622387

MySql Char için;
BoÅŸta: 0.0142888712882996
Toplam: 1.18662132501602
Gerçek: 1.17233245372772

MySql BIGINT
BoÅŸta: 0.01428887128830
Toplam: 0.77685088634491
Gerçek: 0.76256201505661

MySql AUTO-INC
BoÅŸta: 0.014288871288300
Toplam: 0.791638641357422
Gerçek: 0.777349770069122

MySql InnoDB and BIGINT
BoÅŸta: 0.014288871288300
Toplam: 0.809741024971008
Gerçek: 0.795452153682709

Kolay gelsin.

Ruby ile KyotoCabinet – 3” üzerine bir yorum

Bir Cevap Yazın

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