ある日いきなり社内勉強会でライトニングトークしてねwwと指命されたので、MySQLの話してきました。以前サイバーエージェントのエンジニアブログに掲載された「redis、それは危険なほどのスピード」という記事で比較対象になったMySQLに関して考察した内容です。
内容を4行でまとめると、
- はてブのツッコミ通りHashインデックス意味ないです
- rangeスキャンの範囲が広すぎるとB-Treeインデックスはむしろ遅い
- 2倍速いはread件数の差。アルゴリズムとデータ構造はDBだって重要
- パーティション刈り込みでRedisレベルにMySQLを高速化
という内容になります。
資料では触れていませんが、テーブルの大部分を取得するrangeスキャンであっても、B-Treeインデックスが有効になるケースがあります。例えばテストに用いたテーブルに対して以下のクエリを投げると…
select point, count(*) from ranking group by point;
B-Treeインデックス無しではソート処理(using temporary, using filesort)が発生して効率の悪いクエリになります。
このクエリの処理時間は、memoryテーブル+インデックスなしの場合に比べて、memoryテーブル+B-treeが2倍高速、InnoDB+B-Treeでも1.5倍高速という結果になりました。InnoDBではcovering indexが発生して高速な処理になったものと思われます。