偶然的一个机会,看到了 http://railsexpress.de/blog/articles/2006/10/05/make-ruby-mysql-create-less-garbage。才知道原来这个C版本的MySQL数据库适配器,居然会为记录中的每一行创建一个列名字符串。而Stefan Kaes做了一个patch可以减少列名字符窜的生成,从而提升查询的性能。
Stefan Kaes还在他的博客里抱怨Ruby/MySQL的作者没有理会他的关于这个改善的mail。不过这已经是2006年底的事了, http://www.tmtm.org/en/mysql/ruby/上,最新版本已经是2.8了(但是用gem install mysql安装不了2.8版)。在version 2.8pre1,已经做了相应的修改。
2007-12-26 version 2.8pre1 for Ruby 1.9.0 Incompat: Mysql::Result#each_hash don't create column name string each row. it's shared. Incompat: Mysql#query with block no longer turn on multi-statements mode automatically.
让我们自己来做个2.8的gem包吧,这样至少在我自己的gem服务器上,可以用gem install mysql来进行安装。
先解压缩MySQL-2.7.gem文件,看看gemspec里都写了些什么。
tar xf mysql-2.7.gem tar xzf data.tar.gz
mysql.gemspec的内容如下。
--- !ruby/object:Gem::Specification rubygems_version: 0.8.11 specification_version: 1 name: mysql version: !ruby/object:Gem::Version version: "2.7" date: 2005-10-10 00:00:00 +02:00 summary: MySQL/Ruby provides the same functions for Ruby programs that the MySQL C API provides for C programs. require_paths: - lib email: [email protected] homepage: http://www.tmtm.org/en/mysql/ruby/ autorequire: mysql has_rdoc: false required_ruby_version: !ruby/object:Gem::Version::Requirement requirements: - - ">" - !ruby/object:Gem::Version version: 0.0.0 version: platform: ruby files: - COPYING - COPYING.ja - README.html - README_ja.html - extconf.rb - mysql.c.in - test.rb - tommy.css - mysql.gemspec extensions: - extconf.rb
而mysql-ruby-2.8.tar.gz中都有些什么文件呢?
COPYING COPYING.ja README.html README_ja.html extconf.rb mysql.c test.rb tommy.css
原来没有mysql.c.in,而多了mysql.c。确认了一下双方的extconf.rb内容,2.8确实可以直接使用mysql.c文件。(2.7里需要对mysql.c.i做一些修改后,最后生成mysql.c)
把2.7的mysql.gemspec拷贝到2.8的目录下,然后修改mysql.gemspec。
把版本由2.7改成2.8,再把mysql.c.in改成mysql.c。
接下来做成新的gem包。
gem build mysql.gemspec
试着安装一下。
$ sudo gem install -l mysql-2.8.gem Building native extensions. This could take a while... Successfully installed mysql-2.8
虽然显示成功了,不过还是要做后续动作的。进到安装好的ruby gem的目录,我这里是/usr/local/lib/ruby/gems/1.8/gems/mysql-2.8.
ruby extconf.rb make && make install
重启rails工程,进行测试吧。对于下边的查询语句。
Product.find(:all,:conditions => 'where id > 500000',:limit => 50)
2.7的时候,执行3000次用了23.2秒。而用2.8之后,只用了16.7秒。性能提升了28%。对于查询返回多条的记录,性能上改进了很多。对于insert,update,delete动作,基本没有变化。
附件里有我做成的gem包。由于上传文件的限制,需要把tar改成gem。
35K的文件居然上传不了?改时间再上传吧。知道原因了,是Chrome不支持这里的文件上传。