MyISAM全盛時代には、こんな参照性能高速化手法がありました。
ALTER TABLE foo_table ORDER BY
sortDESC;
といったクエリで予めテーブルの内容を並び替えておくことで、SELECT時のORDER BY句が省略出来るというものです。
しかしこれ、InnoDBでは使えないので気をつけましょう。
並び替え済みテーブルとはどういうもの?
公式のドキュメントでは以下のように述べられています。
ORDER BY で指定した順番の行で新しいテーブルを作成する事ができます。挿入と削除の後ではテーブルの順番が変わってしまう事を覚えておいて下さい。このオプションは、ほとんど毎回同じ順番で行のクエリを行う場合に便利です。テーブルに大きい変更を行った後にこのオプションを利用すると、高い性能を得る事が可能でしょう。テーブルが、後でカラムをオーダーしたい順番になっていれば、MySQL のソートは簡単になる場合があります。
ORDER BY 構文は、ソートの昇順や降順を指示する為に、それぞれが任意で ASC または DESC が付随する1つか2つのカラム名を指定できます。デフォルトは昇順です。カラム名だけがソート基準として許されていて、任意の式は許されていません。
http://dev.mysql.com/doc/refman/5.1/ja/alter-table.html
パフォーマンスについては以下の記事が参照になります。
MySQLの400万レコードで試すとSELECTで指定したときは6.0018秒に比べ、標準で指定しておいたときは0.0010秒となり、結果も同じです。
ただしこれは1テーブルにつき1カラムにしか指定できません。
また標準で並び順を指定したものをSELECT文でさらに指定をすると、標準で指定してないときと同じ結果になります。
http://kabu-san.com/sql/speedup.html
InnoDBでこのようなクエリを発行するとどうなるか
ORDER BY ignored as there is a user-defined clustered index in the table
というエラーが発生し、何も変更は加えられません。
mysql> ALTER TABLE test_table ORDER BY age DESC; Query OK, 3 rows affected, 1 warning (0.88 sec) Records: 3 Duplicates: 0 Warnings: 1 mysql> show warnings\G *************************** 1. row *************************** Level: Warning Code: 1105 Message: ORDER BY ignored as there is a user-defined clustered index in the table 'test_table' 1 row in set (0.00 sec)
参考サイト
- Why Does the MySQL Query Optimizer choose the secondary index over the clustered primary index?
http://stackoverflow.com/questions/8140958/why-does-the-mysql-query-optimizer-choose-the-secondary-index-over-the-clustered
PlanetMySQL Voting: Vote UP / Vote DOWN