0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

EXPLAINとEXPLAIN ANALYZEの使い方・違いまとめ

0
Posted at

EXPLAINとEXPLAIN ANALYZEの使い方と違いと、アプリケーション開発における注意点まとめ。
自身がはまった点を含め、覚書きも兼ねてまとめました。

MySQLでは、EXPLAIN ANALYZEは8.0.18で追加された機能です。
本記事の内容は、MySQLの場合、それ以降のバージョンが対象となります。

EXPLAINとEXPLAIN ANALYZEの違い

EXPLAIN EXPLAIN ANALYZE
クエリの実行 しない する
実行計画の表示
実際の実行時間
用途 クエリ規模の事前確認 ボトルネックの特定

EXPLAIN

クエリを実際には実行せず、MySQLがどのような実行計画を立てているかを表示します。
統計情報をもとにした推定値のため、あくまで目安となります。
重いクエリを実行する前に規模感を把握したいときに向いています。

出力サンプル

EXPLAIN SELECT * FROM orders WHERE user_id = 1;
実行結果
# 以下、MySQLでの結果
id | select_type | table  | type | key         | rows | Extra
 1 | SIMPLE      | orders | ref  | idx_user_id |   42 | NULL

主な観点

項目 説明
type アクセス方法。refrangeは効率的。ALLはフルスキャンで注意
rows スキャンする推定行数。大きいほど重くなりやすい
key 使用されるインデックス。NULLはインデックス未使用

EXPLAIN ANALYZE

クエリを実際に実行したうえで、各ステップの実行時間・処理行数を計測して表示します。
ボトルネックの特定に向いています。

実際にクエリが発行されます。
重いクエリには先にEXPLAINで規模感の確認を推奨。

出力サンプル

EXPLAIN ANALYZE SELECT * FROM orders WHERE user_id = 1;
実行結果
# 以下、MySQLでの結果
-> Index lookup on orders using idx_user_id (user_id=1)
   (cost=14.71 rows=42) (actual time=0.032..0.187 rows=38 loops=1)

主な観点

項目 説明
actual time 実際の実行時間(単位はms)
rows(actual) 実際に処理した行数。推定と乖離が大きい場合は統計情報が古い可能性あり
loops そのステップが繰り返された回数

注意点:EXPLAIN ANALYZEの結果と実際の実行時間のズレ

EXPLAIN ANALYZEの結果が問題なさそうでも、実際にクライアントから実行すると思ったより時間がかかるケースも。
それには、executing(クエリ実行時間)とfetching(データ返却時間)を考慮する必要があります。

原因:executingとfetchingの違い

フェーズ 内容 EXPLAIN ANALYZEで計測できるか
executing(クエリ実行時間) クエリの処理・絞り込み
fetching(データ返却時間) 結果データのクライアントへの転送

EXPLAIN ANALYZEが計測するのはexecutingのみです。
トータルの時間を計測したい場合は、SQLクライアントなどから直接実行してfetchingにかかる時間も確認する必要があります。

特にORDER BYが絡む場合

挙動
ORDER BYなし 取得できた行から順次返却
ORDER BYあり 全件ソート完了後にまとめて返却

ORDER BYLIMIT を組み合わせた場合は、MySQLの最適化により全件ソートが省略されることがあります。

EXPLAIN ANALYZEのソートノードのコストが小さく見えても、全件ソート後の一括転送が発生することでトータルが大幅に遅くなるケースがあります。
executingだけで判断せず、実際のクライアント実行時間も合わせて確認するのが確実です。

おわりに

EXPLAIN ANALYZEは実際にクエリを実行するため、EXPLAIN ANALYZEで実行して問題なければ大丈夫と思っていたのですが、アプリケーションレベルではfetchingも加味する必要がある点を認識できていませんでした。

今後アプリケーション向けにクエリを組む際は、実際に実行して実行時間に問題がないか確認するよう徹底したいです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?