2011年11月23日水曜日
こうして僕はrailsを遅くした。そしてそこそこ直した。
最近blogの更新が途絶えがちですが、githubが面白くて(汗)...
先日、ruby on rails 3.1.2と3.1.3が矢継ぎ早にリリースされたのですが、実は関与者の一人だったりします。自戒の意味もかねて、経緯とかを書いておきます。
・2011/10/31 無作為に選んだissueを直そうと思った。
このissueを調べ始めたのですが、
色々調べてみるとmysqlのdescribeの問題という事が判明し、結果的にschema dumperの出力がバグってるという事が分かった。
そこで、describeを使わない形(informationスキーマを利用)で修正した。
・2011/11/06 master/3-1-stableにマージされた。
その後やりとりがあって、直ってよかったねという事で取り込まれた。
・2011/11/18 rails 3.1.2がリリースされた。
そりゃま~、ARは初めてだったので嬉しかったです(リリースノートにも名前が載ったし)。
・2011/11/18深夜 問題発覚。
「ActiveRecord 3.1.2 takes 10 times slower than 3.1.1」というissueがあがる。
良く見てみるとmysqlとあるじゃないか!というのも前のリリースからmysqlについて修正したの私だけ(汗)
その後、某スペイン人(Christos Zisopoulosさん)とのやりとりで、"多くのデータベースが存在するmysql"の場合、遅くなる事が判明。
schema dumperの時のみ、元の修正を利用する、pull requestが取り込まれましたが、
抜本解決ではないので、"show index from"を利用する形で修正を進めた。
・2011/11/19 早朝 修正完了。
・2011/11/19 AM9時頃 某スペイン人により効果が確認され、pull requestした。
その後、railsコミッタのjonleightonにマージしてもらう(master/3-1-stable)。
・2011/11/21 sprockets等他の問題も修正され、rails 3.1.3がリリースされた。
ちなみにsprocketsは
「windows環境でasset pipe lineが失敗する」
「ファイルの更新が反映されない場合がある」
問題があり、最終的に2.0.xにダウングレードされました。
途中「速くリリースしろゴラ!」とか言う人がいてビビッタ。
・2011/11/23
超大規模なデータセットの場合、問題がある可能性がありそうな為、再度「show create table」を利用する形で調整中。
・2011/12/5
「show create table」を利用する形での実装が、rails 3.2系にマージされました。
・2011/12/6
さらにrails 3.1系にもback portされました。
■雑感
・世界中で困っている人がいるかと思うとかなりびびった。某スペイン人には多謝。
・この手の、量に対するテストをどう実施していくかは、そもそも根本的な問題。
・私の嘘英語でも何とかやっていけてるのが驚異的。
・gitはコマンド多すぎるが、かなり便利。
2011年4月6日水曜日
indexを作成すると本当に更新性能は下がるのか?
■概要
RDBMSの参照性能を向上させる為に、indexを作成する事は常識だと思います。
ところが「indexを張りすぎると更新性能が悪くなる」と言われており、理屈的にも理解できます(データおよびindexを更新する必要があるから)。
しかし実際どの程度劣化するのか知りたいので、実験してみたいと思います。
■前提
・さくらVPS 512Mコース
・CentOS 5.x
・mysql 5.0.77
・利用テーブル(下記の様なテーブルで順次indexを作成しなおしテストした)
$ mysql -u xxx < insert.sql
■結果
■結論
確かに下がるには、下がるようだ。。という訳でセオリー通りindexの張りすぎには注意が必要のようです。
ただ全体的にy = ax + bの一次関数likeな上昇なので、"+b"がどこに消費されるのかが気になるところです(sql文のparse?)
RDBMSの参照性能を向上させる為に、indexを作成する事は常識だと思います。
ところが「indexを張りすぎると更新性能が悪くなる」と言われており、理屈的にも理解できます(データおよびindexを更新する必要があるから)。
しかし実際どの程度劣化するのか知りたいので、実験してみたいと思います。
■前提
・さくらVPS 512Mコース
・CentOS 5.x
・mysql 5.0.77
・利用テーブル(下記の様なテーブルで順次indexを作成しなおしテストした)
drop table test_table; create table test_table ( id integer auto_increment not null , v1 varchar(30) not null , v2 varchar(30) not null , v3 varchar(30) not null , v4 varchar(30) not null , v5 varchar(30) not null , primary key(id) ); --create index v1_index on test_table(v1); --create index v2_index on test_table(v2); --create index v3_index on test_table(v3); --create index v4_index on test_table(v4); --create index v5_index on test_table(v5);・テストデータ 10万件insert (下記の様なrubyスクリプトを作成し出来上がったinsert.sql文ファイルを実行した)
def random_string(len) (0...len).map{ ('a'..'z').to_a[rand(26)] }.join end open("insert.sql", "wb") do |f| f.write("truncate table test_table;\r\n") f.write("set @time:=now();\r\n") (0...100000).each do |i| v1 = random_string(30) v2 = random_string(30) v3 = random_string(30) v4 = random_string(30) v5 = random_string(30) vals = "'" << [v1, v2, v3, v4, v5].join("','") << "'" f.write("insert into test_table (v1, v2, v3, v4, v5) values (#{vals});\r\n") puts i end f.write("commit;\r\n") f.write("select timediff(now(), @time);\r\n") end
$ mysql -u xxx < insert.sql
■結果
index数 | 1回目 | 2回目 | 3回目 | 4回目 | 5回目 | 平均処理時間(秒) |
0 | 15 | 20 | 14 | 10 | 14 | 12.6 |
1 | 19 | 18 | 16 | 15 | 14 | 16.4 |
2 | 15 | 14 | 18 | 18 | 15 | 16.0 |
3 | 18 | 14 | 17 | 20 | 21 | 18.0 |
4 | 23 | 18 | 18 | 19 | 18 | 19.2 |
5 | 19 | 22 | 19 | 24 | 20 | 20.8 |
■結論
確かに下がるには、下がるようだ。。という訳でセオリー通りindexの張りすぎには注意が必要のようです。
ただ全体的にy = ax + bの一次関数likeな上昇なので、"+b"がどこに消費されるのかが気になるところです(sql文のparse?)
登録:
投稿 (Atom)