【実務・中級編】 random_page_cost設定 – PostgreSQL

PostgreSQLの「random_page_cost」、SSD時代にそのままにしてない?

やあ。最近、PostgreSQLのチューニングについて相談されることが増えたんだけど、現場で意外と見落とされがちなのがこの設定項目なんだ。

そう、`random_page_cost`。

PostgreSQLのデフォルト設定である「4.0」という数字、実はこれ、HDD(ハードディスク)全盛期の名残なんだよね。今は本番環境のほとんどがSSDやNVMeストレージだろ? もし君の環境がそうなら、この値をデフォルトのままにしておくのは、宝の持ち腐れ……いや、むしろプランナに「わざと遠回りな道を選ばせている」ようなものかもしれない。

今日は、この設定が裏で何をやっていて、どう変えるのが「今どき」の最適解なのか、現場の感覚を交えて話していくよ。

—

「ランダムアクセス」って何を指しているのか?

PostgreSQLがクエリを実行するとき、プランナは「インデックスを使うべきか、それともテーブル全体をスキャン(シーケンシャルスキャン)すべきか」を計算するよね。

そのとき、プランナはコストを比較するんだ。

  • seq_page_cost (デフォルト 1.0): 順次読み込みのコスト
  • random_page_cost (デフォルト 4.0): ランダムアクセス読み込みのコスト

HDDの時代、ヘッドが物理的にあちこち動くランダムアクセスは、順次読み込みに比べて数倍〜数十倍遅かった。だから「ランダムアクセスは高いから、できるだけシーケンシャルスキャンを選ぼう」という重み付け(4.0)が必要だったわけだ。

でも、SSDはどうだ? 物理的なヘッドなんてないよね。ランダムアクセスもシーケンシャルアクセスも、ほとんど速度差がない。それなのに、プランナには「ランダムアクセスはシーケンシャルより4倍重い」という古い価値観が刷り込まれたままなんだ。

—

「なぜかインデックスを使ってくれない」の正体

現場でよくあるのが、「インデックスがあるのに、なぜかシーケンシャルスキャンが選ばれて遅い」というケース。

`EXPLAIN` を叩いてみて、「いや、そのインデックス使えば一瞬じゃん!」と突っ込みたくなることがあったら、十中八九この `random_page_cost` が悪さをしている。プランナが「インデックス検索(ランダムアクセス)はコストが高いから、テーブル全体を読み込んだほうがマシだ」と勘違いしているんだよ。

—

実践:どう設定を変えるべきか?

今の現場で僕が推奨しているのは、SSD環境なら `1.1` くらいに下げることだ。

「えっ、1.0(シーケンシャルと同じ)じゃないの?」と思うかもしれないけど、完全に同じにすると、プランナが強気にインデックスを選びすぎて、かえって効率が悪くなることもある。少しだけコストを乗せておくのが、経験上もっとも安定するチューニングだね。

設定方法(例)

特定のセッションだけで試したいなら、SQLでサクッと確認できる。

— 一時的に値を変更して実行計画を確認する
SET random_page_cost = 1.1;

EXPLAIN ANALYZE
SELECT FROM users WHERE email = ‘hoge@example.com’;

もしこれでプランが変わるようなら、設定ファイル(`postgresql.conf`)に書き込んで永続化しよう。

postgresql.conf
random_page_cost = 1.1

※設定を変えた後は、必ず `SELECT pg_reload_conf();` を忘れずにね。

—

注意点:闇雲にいじるのはNG

一つだけ釘を刺しておくと、この設定は魔法の杖じゃない。

  • メモリが足りない場合: インデックスを多用させすぎると、メモリ上のキャッシュ効率が落ちて、逆にスループットが下がることもある。
  • データサイズ: テーブルが小さすぎてメモリに乗り切っている場合、そもそもこの設定の影響は軽微だ。

まずは本番環境のコピーやステージング環境で、重たいクエリの実行計画がどう変わるか、しっかり `EXPLAIN` で比較検証してほしい。数値を変えて「直感的に速くなった気がする」なんてのはエンジニアの仕事じゃない。ちゃんと数字で根拠を持つことだね。

—

まとめ

  • `random_page_cost` のデフォルト「4.0」はHDD時代の遺物。
  • SSD環境なら「1.1」前後まで下げるのが現代の定石。
  • 「なぜかインデックスが使われない」と思ったら、まずここを疑うべし。

チューニングってのは、エンジンの中身を知る作業だ。PostgreSQLがどう考えて動いているのか、少し想像できるようになると、途端に面白くなってくるぞ。

また何か詰まったら、いつでも聞いてくれ。一緒に最高に速いクエリを追い求めていこう。

コメント

タイトルとURLをコピーしました