EXPLAIN は、クエリの実行の手順を見せる
EXPLAIN は、データベースがクエリをどんな手順で実行するかを見せる命令です。この手順を実行計画と呼びます。
実行計画を読めば、クエリが速い理由や遅い理由を、時間を測らなくても説明できます。
まず、一番短いクエリの計画を見ましょう。
このレッスンのゴール
メモ
EXPLAIN を読んで、クエリの手順を説明できる。
重要な言葉
| ことば | いみ | れい |
|---|---|---|
| 実行計画 | データベースが決めた、クエリを実行する手順 | |
| EXPLAIN | 実行せずに、実行計画だけを表示する命令 | |
| スキャン | 表の行を読み取ること | Seq Scan |
| フィルター | 条件に合わない行を捨てること | Filters |
| ハッシュ結合 | 2つの表を、キーの照合で結ぶやり方 | Hash Join |
| 推定行数 | データベースが予想した行の数。実際の数ではない |
学生が入力するセルは、このプレビューでは空白です。
実行計画は、下から上へ読む
explain を select の前に付けます。計画だけが表示され、クエリは実行されません。
計画は、四角を積んだ木の形です。一番下の四角が、表の読み取りです。データは下から上へ流れて、最後に答えになります。
試す: 一番短い計画
-- 計画だけを見ます。クエリは実行されません。
explain
select amount from orders;
例: 計画に出る四角の名前
| 四角の名前 | 意味 |
|---|---|
| Seq Scan | 表の行を順に読み取る。読む列(Projections)も書かれる |
| Filters | 読み取りの中で、条件に合わない行を捨てる |
| Hash Join | 2つの表を、キーの照合で結ぶ |
| Hash Group By | グループごとに、集計を計算する |
| Projection | 次の四角に渡す列を選ぶ、または計算する |
学生が入力するセルは、このプレビューでは空白です。
読む列は、計画にも書かれている
さきほどの計画の Seq Scan には、Projections: amount と書かれています。orders には4つの列がありますが、読むのは amount だけです。
これが、第1回で学んだ、列指向の読み方です。計画で目に見えます。
試す: 条件が計画に入る場所
-- 条件を付けると、計画のどこに現れるか見ましょう。
explain
select sum(amount) from orders where amount > 5000;
絞り込みは、結合の前に済ませたい
結合の前に行を減らせば、結合が見る行が減ります。分析では、とても大事な考え方です。
次の2つの Run を比べましょう。1つ目は where を join のあとに書き、2つ目は先に orders を絞ります。
試す: where を結合の後ろに書く
-- 結合と集計の計画です。where は、join の後ろに書いてあります。
explain
select c.city, sum(o.amount) as total
from orders o
join customers c on c.customer_id = o.customer_id
where o.order_date >= '2026-01-01'
group by c.city;
試す: 先に絞ってから結合する
-- 先に orders を絞ってから、結合します。
explain
with recent as (
select customer_id, amount from orders where order_date >= '2026-01-01'
)
select c.city, sum(r.amount) as total
from recent r
join customers c on c.customer_id = r.customer_id
group by c.city;
DuckDB は、自分で絞り込みを先に回す
2つの計画を比べると、どちらも orders の Seq Scan の中に、order_date の条件(Filters)が入っています。DuckDB が、自分で絞り込みを先に回したのです。
それでも、先に絞る形で書く価値はあります。意図が読む人に伝わり、自動で回せない複雑なクエリでも、絞り込みが先になります。
よくある間違い
注意
計画の「~4 rows」を、実際の行数だと思ってはいけません。データベースの予想です。EXPLAIN は実行しないので、実際の時間も載りません。
さらに挑戦
try-first の計画で、customers の Seq Scan に Filters が付かないのはなぜでしょうか。customers には、絞る条件を書いていません。
次に、explain を explain analyze に変えるとどうなるか、考えてみましょう。実行するかどうかが違います。