MySQLでインデックスがある場合のINSERTの負荷を見てみる

MySQLで大量のデータを追加してみる
の続き

インデックスがあるとINSERTはどれくらい負荷がかかるのか気になったので、
ちょっと確認してみた。

今回使用するテーブル

今回は下記のテーブルに追加して確認してみる。

create table sample (
  id      int         NOT NULL AUTO_INCREMENT,
  c1      int         NOT NULL,
  c2      int         NOT NULL,
  c3      int         NOT NULL,
  PRIMARY KEY (id)
) ENGINE=InnoDB;

試すパターン

下記のパターンを試す。

選択性のパターン

選択性が高い場合と低い場合の2パターンを試す。

選択性が高いパターンの場合は、下記のINSERTを流す。
c1,c2,c3に1〜100万の値が設定される。

insert into sample (c1, c2, c3)
 select
  FLOOR(RAND()*1000000 + 1),
  FLOOR(RAND()*1000000 + 1),
  FLOOR(RAND()*1000000 + 1)
 from tmp t1, tmp t2, tmp t3, tmp t4, tmp t5;

選択性が低いパターンの場合は、下記のINSERTを流す。
c1,c2,c3に0 or 1の値が設定される。

insert into sample (c1, c2, c3)
 select
  FLOOR(RAND()*2),
  FLOOR(RAND()*2),
  FLOOR(RAND()*2)
 from tmp t1, tmp t2, tmp t3, tmp t4, tmp t5;
インデックスのパターン

インデックスのパターンは下記の4つを試す。
(1)インデックス無し
(2)インデックス1つ

alter table sample add index (c1);

(3)インデックス3つ

alter table sample add index (c1);
alter table sample add index (c2);
alter table sample add index (c3);

(4)複合インデックス1つ

alter table sample add index (c1, c2, c3);

結果

100万件のINSERTを5回行った。結果、下記のようになった。

選択性が高い場合
パターン 100件目 200万件目 300万件目 400万件目 500万件目
(1)インデックス無し 0.64 sec 0.66 sec 0.64 sec 0.59 sec 0.55 sec
(2)インデックス1つ 1.03 sec 1.11 sec 2.32 sec 6.69 sec 9.03 sec
(3)インデックス3つ 2.43 sec 18.11 sec 29.32 sec 29.79 sec 36.23 sec
(4)複合インデックス1つ 1.08 sec 1.64 sec 6.14 sec 7.76 sec 10.28 sec

選択性が低い場合
パターン 100件目 200万件目 300万件目 400万件目 500万件目
(1)インデックス無し 0.54 sec 0.55 sec 0.59 sec 0.56 sec 0.57 sec
(2)インデックス1つ 0.78 sec 0.72 sec 0.82 sec 0.78 sec 0.74 sec
(3)インデックス3つ 1.24 sec 1.24 sec 1.18 sec 1.23 sec 1.18 sec
(4)複合インデックス1つ 0.80 sec 0.83 sec 0.85 sec 0.80 sec 0.80 sec


試してみた結果、下記のような感じ。
・選択性が高い場合ほど(よりユニークに近い値を入れる場合ほど)INSERTの負荷が高い。
・インデックス3つより複合インデックス1つのほうが負荷が低い。
・この程度の確認ではよく分からない。