このトピックでは、コスト計算と関連する数式について説明します。
コスト計算モデル
| コスト | デフォルト値 | 説明 |
| seq_page_cost | 1.0 | ページのシーケンシャルスキャンのコスト。 |
| random_page_cost | 4.0 | ページ上のランダムスキャンのコスト。 |
| cpu_tuple_cost | 0.01 | 単一の行を処理するコスト。 |
| cpu_index_tuple_cost | 0.005 | インデックスエントリを処理するコスト。 |
| cpu_operator_cost | 0.0025 | 各関数または演算子の処理コスト。 |
全表スキャン
postgres=# explain select * from test where id <1000;
クエリ計画
----------------------------------------------------------
テスト時のSeqスキャン (コスト=0.00 .. 1693.00行=5680幅=4)
フィルター: (id < 1000)
(2行)
postgres=# select relpages、relname='test' のpg_classからのreltuples;
relpages | reltuples
------------+-----------
443 | 100000
(1行) コストを計算するために、次の式が用意されています。
- TOTAL_COST = CPUコスト + I/Oコスト
- CPUコスト=cpu_tuple_cost × reltuples + cpu_operator_cost × reltuples
- CPUコスト=0.01 × 100000 + 0.0025 × 100000 = 1250.0
- I/Oコスト=seq_page_cost × relpages
- I/Oコスト=1.0 × 443 = 443
- TOTAL_COST = 1250 + 443 = 1693
インデックススキャン
postgres=# explain select * from test where id =1414;
クエリ計画
-------------------------------------------------------------------------------
インデックスのみテスト時にtest_id_idxを使用してスキャン (コスト=0.29 .. 72.66行=30幅=4)
Index Cond :( id = 1414)
(2行) コストを計算するために、次の式が用意されています。
- RUN_COST = CPUコスト + I/Oコスト
- CPUコスト=インデックススキャンのCPUコスト + テーブルスキャンのCPUコスト
- インデックススキャンのCPUコスト=選択性 × インデックスエントリ数 × (cpu_index_tuple_cost + cpu_operator_cost)
- テーブルスキャンのCPUコスト=選択率 × テーブルの行数 × cpu_tuple_cost
インデックススキャンのCPUコストを計算する
postgres=# select most_common_freqs[array_position((most_common_vals::text)::real[],1414::real)] from pg_stats where tablename ='test';
most_common_freqs
-------------------
0.0003
## 選択率=0.0003
postgres=# select relpages、relname='test_id_idx 'のpg_classからのreltuples;
relpages | reltuples
----------+-----------
276 | 100000
## インデックスエントリ数=100000インデックスページ数=276
postgres=# select relpages、relname='test' のpg_classからのreltuples;
relpages | reltuples
----------+-----------
443 | 100000
## テーブルの行数=100000テーブルのページ数=443 この例では、次のCPUコストが計算されます。
- インデックススキャンのCPUコスト=0.0003 × 100000 × (0.0025 + 0.005) = 0.22500000
- テーブルスキャンのCPUコスト=0.0003 × 100000 × 0.01 = 0.300000
- CPUコスト=0.300000 + 0.22500000 = 0.52500000
インデックススキャンのI/Oコストを計算する
インデックススキャンのI/Oコスト=ceil (選択性 × インデックスページ数) × random_page_cost
テーブルスキャンのI/Oコスト=max_io_cost + 相関係数 × 相関係数 × (min_io_cost - max_io_cost)
max_io_cost=選択率 × 行数 × random_page_cost = 120
min_io_cost = 1 × random_page_cost + (ceil [選択性 × テーブルページ数] - 1) × seq_page_cost = 4
postgres=# tablename ='test' であるpg_statsから相関を選択します。
相関
-------------
0.670535
相関係数=0.670535
I/Oコスト=4 + 67.844406397900 = 71.844406397900 この例では、次のI/Oコストが計算されます。
- RUN_COST = 71.844406397900 + 0.52500000 = 72.369406397900
- START_COST = 0.29
- TOTAL_COST = 72.369406397900 + 0.29 = 72.659406397900 ≒ 72.66