MySQLでインデックスがある場合のINSERTの負荷を見てみる
インデックスがあると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つのほうが負荷が低い。
・この程度の確認ではよく分からない。