random_page_cost パラメータ
random_page_cost
はディスクからのランダムページアクセスのコストを制御するパラメータでクエリプランナのにコスト計算に影響する。
現在の設定値は以下で確認できる。
SHOW random_page_cost;
または pg_settings
システムビューから確認することもできる。
SELECT name, setting, unit, context FROM pg_settings WHERE name = 'random_page_cost';
現在の接続に対する値は以下のように変更することができる。
SET random_page_cost TO 1.1;
グローバルに設定する場合は postgresql.conf
で定義するか、RDS の場合はパラメータグループで定義することとなる。
テーブルスペースに対して設定することもできる。
ALTER TABLESPACE <name> SET (random_page_cost = 1.1)
デフォルト値は src\include\optimizer\cost.h
の中の DEFAULT_RANDOM_PAGE_COST
で、4.0
と定義されている。
/* defaults for costsize.c's Cost parameters */ /* NB: cost-estimation code should use the variables, not these constants! */ /* If you change these, update backend/utils/misc/postgresql.conf.sample */ #define DEFAULT_SEQ_PAGE_COST 1.0 #define DEFAULT_RANDOM_PAGE_COST 4.0 #define DEFAULT_CPU_TUPLE_COST 0.01 #define DEFAULT_CPU_INDEX_TUPLE_COST 0.005 #define DEFAULT_CPU_OPERATOR_COST 0.0025 #define DEFAULT_PARALLEL_TUPLE_COST 0.1 #define DEFAULT_PARALLEL_SETUP_COST 1000.0
これらの値は、シーケンシャルアクセスのコストを 1.0
とした時の相対値である。
random_page_cost の意味合い
random_page_cost
の値(デフォルト値 4.0
)は、前述の cost.h
で定義される他のコストパラメータとの相対値であり、ディスクからのランダムページアクセスコストの相対的な大きさを表す。
シーケンシャルアクセスのコストパラメータである seq_page_cost
の値は 1.0
である。これは、シーケンシャルアクセスのコストはランダムページアクセスのコストの 1/4 として見積もられることを意味する。クエリプランナは、この値を元にコスト計算を行い、よりコストの低い実行計画を選択することとなる。
ソース上では optimizer で実行計画が作られ、コスト計算は主に backend\optimizer\path\costsize.cなどで算出される。
random_page_cost
のデフォルト値である 4.0 は、HDDのランダムアクセスをシーケンシャルアクセスの 40 倍遅く、ランダム読み取りの 90% がキャッシュされる(通常インデックススキャンのようなランダムアクセスは、そのほとんどがキャッシュされているはず)と想定したものと考えることができる。
random_page_cost
の値が高いほどシーケンシャルスキャンが優先され、値が低いほどインデックススキャンが優先される傾向がある。
値が低いほど(ハッシュ結合の代わりに)ネステッドループ結合が優先される傾向がある。
random_page_cost の設定値
random_page_cost
のデフォルト値はHDDを想定した保守的な値に設定されている。
ストレージとして SSD を利用している場合は、より小さな値(2~1)に設定すべきである。
使用されるインデックスのほとんどがメモリや Aurora 階層キャッシュに収まる場合も、random_page_cost
の値を seq_page_cost
に近い値に変更するのが適切である。
さらに、データベースが完全にRAMにキャッシュされるようなケースでは、ページの取り出しコストは通常よりもかなり小さくなるため、CPUパラメータに対して両値を小さく設定することもできる。
SSD ストレージの場合は、1.1
に設定されることが多い。