index が定義されていた場合、そ のテーブルはアクセスが集中する重要なテーブルかもしれません。また、 secondary index が多いということは、それだけ更新処理が重くなった り、ロックの競合が発生しやすいことになります。 • MySQL は Multi Column Index を定義できて、それをうまく使うと、本 当に必要な index の数は、かなり減らせると考えられます。 • とてもざっくり考えると、ゲーム用途なら多くの場合、 secondary index の数は 2-3 程度でもかなり有効であり、片手で数えられないほど index が定義されていたならば、何か設計を見直したほうが良い気がします。 • 前述したように、ローテーションすることでテーブルを小さく保てるなら、 index を追加す るより、テーブルを小さくすることを、検討しても良いでしょう。 index が多すぎるなら、設計を見直す 47
があったとします。 • SELECT * FROM table1 FORCE INDEX (col1_index) WHERE col1=1 ORDER BY id; • 私の場合、次のように書けないか検討します。 • SELECT * FROM table1 IGNORE INDEX (PRIMARY) WHERE col1=1 ORDER BY id; • MySQL のインデックスヒントには、次のような特性があります。 • https://dev.mysql.com/doc/refman/5.6/ja/index-hints.html • index_name 値は、完全なインデックス名である必要はありません。インデックス名のあい まいでないプリフィクスにすることができます。プリフィクスがあいまいな場合は、エラーが発 生します。 • PRIMARY は不変かつ完全なインデックス名なので、このあたりの振る舞 いに悩まされず、使うことが可能です。 補足・IGNORE INDEX PRIMARY 49
で、 Read-Only Transaction が最適化されました。 • https://dev.mysql.com/doc/refman/5.6/ja/innodb-performance-ro-txn.html • MySQL 5.7 で、さらに次の最適化が追加されました。 • https://dev.mysql.com/doc/refman/5.7/en/innodb-performance-ro-txn.html • The transaction is started without the READ ONLY option, but no updates or statements that explicitly lock rows have been executed yet. Until updates or explicit locks are required, a transaction stays in read-only mode. • autocommit が default の ON のままで non-locking な SELECT を実行すると、 InnoDB 的に軽くなります。 READ ONLY TRANSACTION 56