今回は、筆者が気をつけている、MySQLのクエリチューニングの基本的な考え方について、紹介しようと思います。
基本的な指針としては、下記を守ることが重要です。
上記の基本的な指針に基づいて、クエリを組み立てる際は以下の点を考慮するとよいと思います。
基本的な指針としては、下記を守ることが重要です。
- MySQLがクエリの実行で使用する領域(≒メモリ使用量)を減らす。
- クエリ対象の行を減らす (INDEX, サマリーテーブルを駆使)。
上記の基本的な指針に基づいて、クエリを組み立てる際は以下の点を考慮するとよいと思います。
- SELECTで指定する行は少なくする。
- JOINするテーブルの数は減らす。
- TEXTや大きいサイズのVARACHARでのORDER BYは極力避ける。SUBSTRなどを使ってカラムの一部データのみを使うことも考慮。
- EXPLAINを実行した際に Extra: Using where; Using temporary; Using filesort と表示される場合は要チェック。
- 確認部分: 巨大なTemporaryテーブルが作成されないように注意。
- 対策: 「ソート部分でINDEXを使えないか」「サマリーテーブルを使って余計なJOINを減らしソート対象の行数を減らせないか」を検討。
- INDEXを効かせる。
- テーブル設計段階でどのカラムにINDEXを張るかをしっかり検討 (当たり前ですが。)
- 特にソートの必要がある場合は、できるだけINDEXやPRIMARY KEYを利用できるようにクエリやテーブルを設計。
- 基本MySQLのクエリオプティマイザに従うべきですが、あえて特定のINDEXを効かせる/効かせない場合は
- FORCE INDEX
- STRAIGHT_JOIN
- 想定される状況が限定的
- 解決しようとしているクエリの問題が明確
- 性能改善度合いが大きい
- 複雑なネストクエリは避ける。
- 確認部分: Temporaryテーブル(INDEXが効かない!)が作成される可能性が高い上、メモリも大量に消費
- 対策: 1クエリで無理に済まそうとするより、単純な小さいクエリを複数回呼ぶほうが高速、安定する場合もあるので、検討。
- 全件一括更新、削除すると、テーブルロックが長時間発生するので、(可能であれば)数千行単位で分割して処理する。
コメント