cost / rows / width の意味(cost は秒ではない)
cost は「ページを 1 枚順に読む手間を 1.0 とした相対値」で、秒ではない。開始コストと総コストの 2 つが表示される。rows は 1 回の実行で返ると見積もった行数、width は 1 行の平均バイト数の見積り。
どのノードにも同じ 3 つが付く
実行計画のどのノードにも cost / rows / width が 付いています。この 3 つは全部「見積り」で、 実際に実行した結果ではありません。
Seq Scan on members (cost=0.00..10417.00 rows=500000 width=34) (actual time=0.006..22.839 rows=500000.00 loops=1)
Filter: (age >= 20)
Rows Removed by Filter: 0
Buffers: shared hit=4167
Planning:
Buffers: shared hit=104
Planning Time: 0.145 ms
Execution Time: 33.422 msSeq Scan。50 万行を順に読む計画。
PostgreSQL 18.6 / 2026-08-22 採取 / 並列・JIT は OFF
(cost=0.00..10417.00 rows=500000 width=34) の読み方を 1 つずつ見ます。
cost は秒ではない
いちばん誤解されるのがここです。cost の単位は秒でもミリ秒でもありません。ページを 1 枚順番に読む手間を 1.0 とした相対値です。
だから cost=10417.00 と Execution Time: 33 ms を並べて比べても意味がありません。cost は cost どうし、時間は時間どうしで比べます。
ページとは、データベースがディスクとやりとりする最小単位です (PostgreSQL では 8KB)。1 行だけ欲しくても、その行が入っているページを 1 枚まるごと 読みます(データはどう置かれているか)。
おおまかな内訳はこうです(いずれも既定値)。
- ページを 1 枚順番に読む =
1.0(seq_page_cost) - ページを 1 枚バラバラに読む =
4.0(random_page_cost。4 倍高いと仮定している) - 1 行を処理する =
0.01(cpu_tuple_cost) - 条件式を 1 回評価する =
0.0025(cpu_operator_cost)
上の Seq Scan に当てはめます。Buffers: shared hit=4167 が実際に読んだページ数です(プランナが見積りに使うのは統計が持つページ数 relpages で、 ここでは一致しています。統計が古いと両者はずれます)。4,167 ページを順に読み、50 万行を処理し、Filter: (age >= 20) の条件式を50 万回評価します。
4167 × 1.0 = 4167.00 ページを順に読む
+ 500000 × 0.01 = 5000.00 1 行ずつ処理する
+ 500000 × 0.0025 = 1250.00 条件式を 1 回ずつ評価する
----------
10417.00計画に出ている cost=0.00..10417.00 と端数まで一致します。cost は当てずっぽうではなく、この 4 つの定数と見積り行数から計算で出せます。
定数の一覧と既定値は PostgreSQL 公式ドキュメント Planner Cost Constantsにあります。
2 つ書いてあるのは「開始」と「全部」
cost=0.00..10417.00 の左は最初の 1 行を返せるまで、 右は全部返し終わるまでのコストです。
Seq Scanは 1 行目をすぐ返せるので左が0.00Sortは全部読み終わるまで 1 行も返せないので、左と右がほぼ同じになります
LIMIT が付いているクエリでは左の値が効きます。 「全部やると高いが、最初の 10 行だけなら安い」という計画が選ばれるためです。
rows は見積りの行数
rows=500000 はこのノードが返すと見積もった行数です。 実際に何行返ったかは、EXPLAIN (ANALYZE) を付けたときだけ分かります。
Index Scan using members_pkey on members (cost=0.42..8.44 rows=1 width=34) (actual time=0.015..0.016 rows=1.00 loops=1)
Index Cond: (id = 42)
Index Searches: 1
Planning Time: 0.253 ms
Execution Time: 0.046 msIndex Scan。1 行だけ返る見積り。
PostgreSQL 18.6 / 2026-08-22 採取 / 並列・JIT は OFF
この計画では rows=1 です。主キーで 1 行引いているので当然ですが、この数字は統計情報から計算されたもので、当てずっぽうではありません。 どうやって出しているかは見積り行数の内訳で最後まで追います。
rows が外れると計画が壊れます。少なく見積もりすぎると「何度もまわしても安い」と判断してしまうためです。 その実例は遅いノードの見つけ方にあります。
rows は「1 回あたり」の数字です。そのノードが繰り返し実行される場合、rows は1 回の実行で返る行数を指します。 総数を知るには loops を掛けます(EXPLAIN ANALYZE の見方)。
width は 1 行の平均バイト数
width=34 はそのノードが返す 1 行の平均バイト数の見積りです。 直接読む機会は少ないですが、次の 2 つで効いてきます。
- ソートやハッシュがメモリに収まるかの判断。 行数 × width が作業メモリを超えると一時ファイルに落ちます(ソートとメモリ)
- 統計が無いときの行数の見積り。width の見積りが外れると行数の見積りも連鎖して外れます(見積り行数の内訳)
必要な列だけ選べば width は小さくなります。SELECT * をやめると効くのはこの部分です。
まとめ
cost— 秒ではない。相対値。左が開始、右が全部rows— 見積りの行数。1 回あたりwidth— 1 行の平均バイト数の見積り
次はEXPLAIN ANALYZEで、見積りと実測を並べて見るところに進みます。
よくある疑問
関連トピック
もっと学びたい方へ(おすすめ書籍)
PostgreSQLの内部構造・ストレージ・インデックス機構を丁寧に解説。設計と運用計画の鉄則が学べる。
「なぜこの書き方が速いのか」を実行計画から説明する一冊。条件分岐・集約・結合・更新のそれぞれで、良い書き方と悪い書き方を対比しながら読める。
テーブル設計と正規化、パフォーマンス考慮のインデックス設計まで実務レベルで学べる定番書。第2版ではクラウド対応も強化。
ER 図をどう「使える設計」に落とすか、実務の判断まで踏み込んだ入門書。エンティティの切り出しから多対多の扱いまで具体例が豊富。
ドリル 256 問を実際に打ちながら進める SQL の入門書。付属のブラウザ環境で演習できるので、SELECT から結合・集約までを環境構築で止まらずに通せる。
SQLの本質的な使い方と、インデックスが効くクエリの書き方を学べる。ウィンドウ関数など現代SQLも網羅。
実務でやりがちなSQL・DB設計のアンチパターンとその回避策を体系的に学べる。
IPAデータベーススペシャリスト試験の総合対策書。インデックス関連は本サイトと合わせて学ぶと理解が深まる。
リレーショナルモデルの理論から、インデックス設計を含む実務で使えるSQLまで解説。
本セクションはAmazonアソシエイトのリンクを含みます。
もっと深くDBを学びたい方へ。
たいてっくが、SQL・データベース設計・パフォーマンスチューニング・IPAデータベーススペシャリスト対策まで、1対1で学習をサポートします。まずは無料相談から。
「教え方も上手で、お人柄も良いメンターです。DB周りの知識はもちろん、何より、しっかり教えてあげようという姿勢がとてもありがたかったです。データベース、SQLの学習を考えている方にはおススメです。」
— H 様(DB・SQL コース受講)「体系的に知識を教えてくださり、実際の業務でも大変役立っております。特に短い時間で効率よく知識の習得や、練習をできているのは期待以上でした。」
— M 様(DB・SQL コース受講)「大変充実したコンテンツでわかりやすいご説明をありがとうございました。基本的な質問にも丁寧にご説明いただき、また業務のご相談にも乗って頂き大変有意義な時間でした。」
— K 様(DB・SQL コース受講)