Ruby/MySQL 2.9.9

Ruby/MySQL 2.9.9 を作りました。

Ruby/MySQL

Ruby/MySQLRuby から MySQL を使用するためのライブラリです。

特徴:

  • Ruby だけで書かれているためコンパイル不要
  • Ruby 1.9 の Encoding 対応
  • Ruby のスレッドでも動作
  • MySQL C API ライブラリ(libmysqlclient)を使用していない
  • 遅い

今回のリリースは主に速度改善です。

インストール

% gem install ruby-mysql

速度改善のため一部をCで書いた ruby-mysql-ext というのもあります。
こちらは、インストールするためにコンパイルが必要です。

% gem install ruby-mysql-ext

速度

簡単に速度を測ってみました。ちゃんと測ってないので雰囲気です。

f:id:tmtms:20120618232922p:image:w640

(select の結果が正しくなかったので取り直しました)

計測環境:

ThinkPad X220 Core i5-2410M
Memory 8GB 
Ubuntu Linux 12.04
MySQL 5.5.25
Ruby 1.9.3p194 / 1.8.7p352

グラフの縦軸は秒です。

処理内容はこんな感じです。詳細は https://github.com/tmtm/ruby-mysql/tree/master/bench を見てください。

insert
10万レコードのINSERT
insert(prepare)
10万レコードをプリペアドステートメントでINSERT
select
10万レコードのSELECT(10000レコードを10回)
select(prepare)
10万レコードをプリペアドステートメントでSELECT(〃)
many_query
結果を返さないクエリを10万回発行

グラフ中の MySQL/Ruby というのは MySQL の C APIライブラリ libmysqlclient を使用したものです。すべて C で書かれているためやっぱり速いです。

最速な環境を求めるのであれば MySQL/Ruby を使うのもいいと思いますが、今後はおそらくメンテされません。mysql2 というライブラリもあるのでそれを使うのもいいと思います。

マルチスレッド

Ruby/MySQLRuby で書かれているため、Ruby のスレッドを使用して、時間がかかるクエリ実行中でも別の処理を行うことができます。一部 C で書かれた Ext版でも、スレッド切り替えを妨げてるようなことはしていないつもりです。

たとえば次のスクリプトを Ruby/MySQL で実行すると、クエリ実行中の5秒の間でもスレッドが動いて数字を出力します。

require 'mysql'

my = Mysql.new('localhost', 'root', 'password')
Thread.new do
  10.times do |i|
    p i
    sleep 1
  end
end
my.query('select sleep(5)')   # 5秒掛かるクエリ

MySQL/Ruby を使用した場合は5秒間何も表示せずに終了してしまいます。

Ext版(一部 C版)の注意

内部でエンディアンに依存した箇所があるのですが、手元にビッグエンディアン環境がないため試せてません。

GCC でしかコンパイルしてないので、他のコンパイラでコンパイルできるかどうかわかりません。

Windows 環境では動かないような気がします。なんとなく。