実行計画を読む
実行計画のツリーを下から上へと辿る読み方を習得。cost、rows、actual time、loops の意味と、推定と実測のズレから問題箇所を特定します。
前提: 第 1 章で作った idx_customer がある。
- 実行計画の木は、どう読むか
- 各行の cost / rows / actual time / loops は何を表すか
- 「推定と実測のズレ」は、なぜ最初に見るべき場所なのか
実行計画とは何か(改めて)
データベースは SQL を受け取ると、クエリを実際に実行する前に「どのような探索手順で処理するか」を決定します。 この処理手順書を実行計画(Execution Plan)と呼び、計画を自動策定する頭脳となるエンジンがオプティマイザです。EXPLAIN は、オプティマイザが立てた計画を人間向けに出力するコマンドであり、主に 2 つの形式があります。
EXPLAIN FORMAT=TREE SELECT …— クエリを実際には実行せず、事前に策定された予定の計画を出力します。行数等はすべて統計情報に基づく推定値です(ラボの「推定プラン」タブ)。EXPLAIN ANALYZE SELECT …— クエリを実際に完走させ、各ステップで実際に消費された時間・処理された行数を実行計画に付記して出力します(ラボの「実測プラン」タブ)。
実行計画の基本: ツリー構造を読み解く
第 1 章で確認したインデックスなしクエリの実測プランを再掲します。
-> Aggregate: count(0), avg(order_items.unit_price) (cost=3.6e+6 rows=1) (actual time=4500..4500 rows=1 loops=1)
-> Filter: (order_items.customer_id = 123456) (cost=3.3e+6 rows=3.2e+6) (actual time=190..4500 rows=64 loops=1)
-> Table scan on order_items (cost=3.3e+6 rows=32e+6) (actual time=0.5..3900 rows=32e+6 loops=1)インデント(字下げ)で階層化された 3 行が表示されており、各行をノード(処理ステップ)と呼びます。字下げが深いほど上流の処理となり、下から上に向かってデータが流れていきます。
- Table scan on order_items — order_items テーブルの全 3,200 万行を端から読み込み、上位ノードへ渡します。
- Filter: (customer_id = 123456) — 渡された行のうち条件に合致する行だけを抽出し、64 行に絞り込んで上位へ渡します。
- Aggregate: count, avg — 最終的に受け取った 64 行をもとに件数と平均値を算出し、1 行の結果として返却します。
ツリー構造になっている理由は、テーブル結合(JOIN)のように「複数の入力を受け取って 1 つにマージする」分岐処理が存在するためです(第 7 章で詳しく扱います)。入力が 1 系統のみの場合は、このように縦 1 列の直線的な流れになります。 実行計画を読む際の黄金律は、「まず最下段(リーフノード)を見てどこから何行読んだかを確認し、そこから上へ辿りながらどこで行数が減り、どこで時間を消費したかを追跡する」ことです。
無料プレビューはここまで
続きでは、4.5 秒の原因と推定のズレを、cost / rows / actual time / loops から特定します。
ここからの学習は有料プラン(買い切り)となります
¥500 税込・買い切り(追加費用なし)
ご購入いただくと、第二部 2〜10 章(実行計画、選択性、複合インデックス、InnoDB の内部構造、ソートとページング、JOIN、書き込みコストと DDL、ロック、同時実行)の全編、すべてのラボの計測データ再生機能、および章末の理解度確認クイズをご利用いただけます。
※ ご購入時と同じ Google アカウントでログインすることで、すぐに続きを閲覧いただけます。デジタルコンテンツの性質上、購入後の返金は原則としてお受けできません。まずは無料の 13 章と各有料章のプレビューをお試しいただき、ご納得の上でご購入ください。