InnoDB vs MyISAMシリーズでブログ風のテーブル設計にして、
副問い合わせのパフォーマンスを試してみました。
測定環境についてはこちらを参照して下さい。
・データ件数は100万件
・こちらの構造のテーブルをInnoDBとMyISAMで作成して処理速度を比較
・entryとentry2は記事を格納するテーブルで100万件登録されています。
・entry_commentとentry_comment2はコメントを格納するテーブルで、こちらも100万件登録されています。
・PRIMARY KEYであるidには1~1000000の値がセットされています。
・1記事に対して、1コメントが存在しています。・以下の構造のテーブルをInnoDBとMyISAMで作成して処理速度を比較
以下SQL中の「テーブル名 entryとentry_comment」にはMyISAMなら entry2とentry_comment2 がセットされます。
副問い合わせのパフォーマンス比較用のSQL
-
SELECT e.id, e.STATUS,
-
e.category_id,
-
e.user_type,
-
e.name,
-
e.favorites,
-
e.comments,
-
e.trackbacks,
-
e.favorite_permission,
-
e.comment_permission,
-
e.comment_captcha_permission,
-
e.trackback_permission,
-
e.edited,
-
e.image,
-
e.caption,
-
e.user_name,
-
e.created,
-
e.modified,
-
e.removed,
-
e.title,
-
e.body,
-
s.max_created AS max_created
-
FROM entry e, (SELECT c.entry_id,
-
max(c.created) AS max_created
-
FROM entry_comment c
-
WHERE c.user_name = %s
-
AND c.removed IS NULL
-
GROUP BY c.entry_id) s
-
WHERE e.id = s.entry_id
-
AND e.removed IS NULL
-
AND ( e.STATUS = 1 OR e.STATUS = 2)
-
ORDER BY s.max_created
※%sはランダムに変化します。
InnoDBの実行計画(explainの結果)
-
*************************** 1. row ***************************
-
id: 1
-
select_type: PRIMARY
-
TABLE: <derived2>
-
type: system
-
possible_keys: NULL
-
KEY: NULL
-
key_len: NULL
-
ref: NULL
-
rows: 1
-
Extra:
-
*************************** 2. row ***************************
-
id: 1
-
select_type: PRIMARY
-
TABLE: e
-
type: const
-
possible_keys: PRIMARY
-
KEY: PRIMARY
-
key_len: 4
-
ref: const
-
rows: 1
-
Extra:
-
*************************** 3. row ***************************
-
id: 2
-
select_type: DERIVED
-
TABLE: c
-
type: ref
-
possible_keys: entry_comment_idx2,entry_comment_idx3,entry_comment_idx4
-
KEY: entry_comment_idx2
-
key_len: 204
-
ref:
-
rows: 1
-
Extra: USING WHERE; USING TEMPORARY; USING filesort</derived2>
MyISAMの実行計画(explainの結果)
-
*************************** 1. row ***************************
-
id: 1
-
select_type: PRIMARY
-
TABLE: <derived2>
-
type: system
-
possible_keys: NULL
-
KEY: NULL
-
key_len: NULL
-
ref: NULL
-
rows: 0
-
Extra: const row NOT found
-
*************************** 2. row ***************************
-
id: 1
-
select_type: PRIMARY
-
TABLE: e
-
type: eq_ref
-
possible_keys: PRIMARY
-
KEY: PRIMARY
-
key_len: 4
-
ref: const
-
rows: 1
-
Extra: USING WHERE
-
*************************** 3. row ***************************
-
id: 2
-
select_type: DERIVED
-
TABLE: c
-
type: ref
-
possible_keys: entry_comment_idx2,entry_comment_idx3,entry_comment_idx4
-
KEY: entry_comment_idx2
-
key_len: 204
-
ref:
-
rows: 1
-
Extra: USING WHERE; USING TEMPORARY; USING filesort</derived2>
2.rowの表現が食い違っています。
InnoDBは type: const ですが、MyISAMは type: eq_ref となっています。
ただ、両方ともに key: PRIMARY で、 ref: const なので問題ないようです。
計測結果
| スレッド数 | MyISAM | InnoDB |
2~8同時スレッドのピーク時性能で15~20%程度、InnoDBのほうが高速のようです。
同時スレッド数に対するスケーラビリィティは、これまで見てきた通り、MyISAMが優秀で、
おそらく128同時スレッド数あたりでは、優劣が逆転すると思います。
次回はInnerJoinを試してみます。





