「なぜかインデックスを使ってくれない!」を解決。PostgreSQLのSSD最適化術
こんにちは!データベースの世界にどっぷり浸かっているエンジニアです。
今日は、PostgreSQLを使っていると時々遭遇する「せっかくインデックスを張ったのに、データベースがちっとも使ってくれない!」というモヤモヤした悩みについてお話しします。
これ、実はデータベースの設定が「昔の常識」のままになっていることが原因かもしれません。特に、今の時代の速いストレージ(SSD)を使っているなら、ちょっとした「設定のお引越し」をするだけで、検索速度が劇的に変わることがあるんですよ。
—
図書館の本探しで例えてみましょう
データベースがデータを探すとき、大きく分けて2つの方法があります。
1. 全件スキャン(シーケンシャルスキャン):図書館の棚を端から端まで全部見て、お目当ての本を探す方法。
2. インデックススキャン:入り口にある検索カード(索引)を使って、本の場所を特定してから取りに行く方法。
普通に考えれば「2番のほうが速いじゃん!」と思いますよね。でも、PostgreSQLは賢い反面、慎重すぎる性格なんです。
なぜデータベースは「全件スキャン」を選んでしまうのか?
PostgreSQLは、「インデックスを使うと、あちこちの棚に移動しなきゃいけないから時間がかかるかも……」と心配します。
昔のHDD(ハードディスク)は、レコードのヘッドを物理的に動かしてデータを読み取っていたので、あちこちに飛ぶ「ランダムアクセス」は本当に時間がかかったんです。だから、「あちこち移動するくらいなら、端から端まで歩いて探したほうが速いよね」と判断していました。
でも、今のSSDは違いますよね。 SSDはどこに飛んでも爆速です。
今のPostgreSQLは、まだ「HDD時代の慎重さ」を引きずっていることがあるんです。「インデックスを使うと移動コストが高いからやめておこう」という昔の基準のまま判断してしまうと、本当は速いSSD環境なのに、わざわざ遅い全件スキャンを選んでしまう……これが原因です。
—
そこで登場するのが「random_page_cost」
PostgreSQLの設定ファイル(`postgresql.conf`)の中に、`random_page_cost`という設定項目があります。これはまさに、「あちこち移動するコストはどれくらい?」という重み付けの数値です。
デフォルトでは `4.0` になっていることが多いのですが、これをSSD環境に合わせて `1.1` くらいまで下げてみましょう。
どういうことが起きるの?
この数値を下げるということは、データベースに対してこう伝えるのと同じです。
> 「もう昔のHDDじゃないんだよ。あちこち飛んでデータを取ってきても、今のSSDなら全然速いから、遠慮なくインデックスを使っていいよ!」
こう伝えることで、今まで「いや、インデックスを使うと移動が大変だから……」と躊躇していたクエリが、次々とインデックスを活用する賢い動きに変わってくれます。
—
設定のヒント:まずは試してみよう
もし、あなたの環境がSSDなら、以下の手順で試してみてください。
1. `postgresql.conf` を開く。
2. `random_page_cost = 1.1` と書き換える。
3. データベースを再読み込み(または再起動)する。
もちろん、何でもかんでもインデックスが正義というわけではありませんが、多くの「なぜか遅い」というケースは、この設定で解消されます。
注意点として:
設定を変えたあとは、必ず `EXPLAIN` コマンドを使って、実際にクエリの実行計画がどう変わったか確認してくださいね。「本当にインデックスを使ってくれるようになったかな?」と確認する工程こそ、エンジニアとしての醍醐味ですから!
—
最後に
データベースのチューニングと聞くと、「なんだか難しそう」と身構えてしまうかもしれません。でも、今回のように「データベースの性格」を理解して、今のハードウェアに合わせて設定を調整してあげるだけで、驚くほど元気に働いてくれるようになるんです。
あなたのデータベースも、今の速いSSDの力を存分に発揮できていないだけかもしれません。ぜひ一度、この「random_page_cost」を見直してみてくださいね。
それでは、また次回の記事でお会いしましょう!Happy Coding!
コメント