MySQLでインデックスを作成する際、ASC(昇順)やDESC(降順)を指定できるのをご存知でしょうか?
一見すると単なる順序指定に見えますが、クエリの最適化やパフォーマンスに大きな影響を与える場合があります。特に複合インデックスを使う場合には、順序の設計がクエリ効率に直結します。
インデックスの基本:デフォルトはASC(昇順)
MySQLでインデックスを作成する際、以下のように昇順(ASC)や降順(DESC)を指定できます。
CREATE INDEX idx_created_at_asc ON posts (created_at ASC);
CREATE INDEX idx_created_at_desc ON posts (created_at DESC);
ただし、ASCは省略可能で、何も指定しなければ昇順でインデックスが作成されます。
昇順インデックスで降順クエリは使えるのか?
単一カラムのソートであれば、ASCインデックスでもDESCクエリはカバー可能です。
MySQLはインデックスを逆順でスキャンする機能(インデックス逆走)を持っているため、わざわざDESCインデックスを用意しなくても対応できます。
例:
-- インデックスは ASC で作成されている
SELECT * FROM posts ORDER BY created_at DESC LIMIT 10;
このようなクエリでも、MySQLはインデックスを逆走して効率よく結果を取得してくれます。
ASC / DESC の違いが重要になるケース
それでは、DESCインデックスを使うべき状況とはどういったケースなのでしょうか?
特に複合インデックス(Composite Index)では、順序が非常に重要になります。
複合インデックスの例
CREATE INDEX idx_user_date ON logs (user_id ASC, created_at DESC);
このインデックスは、次のようなクエリに対して有効です。
SELECT * FROM logs
WHERE user_id = 1
ORDER BY created_at DESC;
逆に、以下のようなORDER BY created_at ASCのクエリではインデックスが最適に利用されない可能性があります。
SELECT * FROM logs
WHERE user_id = 1
ORDER BY created_at ASC;
MySQLでは複合インデックスの順序すべてがクエリのORDER BYと一致している必要があるためです。順序が一致しないと、ファイルソート(Using filesort)が発生し、パフォーマンスが落ちます。
MySQLバージョンによる違いにも注意
MySQL 5.7以前では、DESCを指定しても、実際には内部的にASCインデックスとして扱われるため、DESCインデックスは意味を持ちません。
しかし、MySQL 8.0以降ではこの制約が解消され、降順のインデックスが使われるようになりました。
| バージョン | DESC指定の扱い |
|---|---|
| MySQL 5.7以下 | 無視される(昇順と同じ扱い) |
| MySQL 8.0以降 | 有効に動作する(パフォーマンス改善が可能) |
インデックスの順序設計:実践的なTips
単一カラムの場合
- デフォルト(
ASC)で問題なし。 -
DESCクエリにも逆走で対応可能。
複合インデックスの場合
- よく使うクエリの
ORDER BYに合わせて、順序を設計する。 - クエリの順序と一致しないとファイルソートが発生する。
実行計画で確認する
-
EXPLAINを使って、インデックスが使われているかどうかを確認。 -
Using filesortが出ている場合は、ソートで余計なコストがかかっている。
インデックス確認コマンド
現在のインデックス情報を確認したいときは、以下のSQLを使用します。
SHOW INDEX FROM posts;
また、クエリ最適化にはEXPLAINの活用が重要です。
EXPLAIN SELECT * FROM posts ORDER BY created_at DESC LIMIT 10;
まとめ
- インデックスの順序(ASC / DESC)は、複合インデックスとORDER BYの最適化で重要。
- 単一カラムなら基本的にASCだけで対応可能。
- 複合インデックスでは、ORDER BYとの一致がパフォーマンスに影響。
- MySQL 8.0以降はDESCインデックスが正式にサポートされている。
- 実行計画(EXPLAIN)を使って、適切にインデックスが利用されているかを確認しよう。