読者です 読者をやめる 読者になる 読者になる

IDを1000ずつ増やす

see http://d.hatena.ne.jp/spiritloose/20080327http://blog.livedoor.jp/sasata299/archives/51280681.html

CREATE TABLE sequence (id INT UNSIGNED NOT NULL) ENGINE=InnoDB;
INSERT INTO  sequence VALUES (100);

CREATE TABLE hoge (
    id INT UNSIGNED NOT NULL PRIMARY KEY DEFAULT 0,
    content TEXT
) ENGINE=MyISAM;

DROP TRIGGER IF EXISTS hoge_set_id;
delimiter //
CREATE TRIGGER hoge_set_id BEFORE INSERT ON hoge
FOR EACH ROW
BEGIN
    UPDATE sequence SET id = LAST_INSERT_ID(id + 1000);
    SET NEW.id = LAST_INSERT_ID();
END;
//
delimiter ;

EC2で別のインスタンスを5つほど立ち上げて、以下のスクリプトをそれぞれで実行。

require 'rubygems'
require 'mysql'

HOST = 'XXX.compute.amazonaws.com'
USER = 'scott'
PASS = 'XXX'
DB   = 'sandbox'

begin
  my = Mysql.new(HOST, USER, PASS, DB)

  100000.times do
    my.query("INSERT INTO hoge (content) VALUES ('hoge')");
  end
ensure
  my.close if my
end


[root@ip-XXX-XXX-XXX-XXX ~]# time ruby test.rb

real 29m58.939s
user 0m0.044s
sys 0m0.068s

30分で50万件だから、277qpsか…おっせー。
ボトルネックになってるのかも。


比較用に普通にauto_incrementを使ってみる。

DROP TABLE IF EXISTS hoge;
CREATE TABLE hoge (
    id INT UNSIGNED NOT NULL PRIMARY KEY auto_increment,
    content TEXT
) ENGINE=MyISAM;

DROP TRIGGER IF EXISTS hoge_set_id;


[root@ip-XXX-XXX-XXX-XXX ~]# time ruby test.rb

real 1m27.934s
user 0m0.048s
sys 0m0.068s

ええええええぇぇぇぇぇぇぇぇぇぇぇぇぇぇぇぇ…

sequenceをMEMORYにしてみよう…

DROP TABLE IF EXISTS sequence;
CREATE TABLE sequence (id INT UNSIGNED NOT NULL) ENGINE=MEMORY;
INSERT INTO  sequence VALUES (100);


[root@ip-XXX-XXX-XXX-XXX ~]# time ruby test.rb

real 1m46.856s
user 0m0.056s
sys 0m0.060s

今度は同じくらい。

ついでにMyISAMも調べる。


[root@ip-XXX-XXX-XXX-XXX ~]# time ruby test.rb

real 2m2.846s
user 0m0.040s
sys 0m0.068s

ふむふむ。


NDBとかだとさらに遅いんだろうか?