こんにちは!データベースの世界へようこそ。
普段、PostgreSQLを触っていて「なんだかクエリの動きが遅いな……」と感じることはありませんか?
実は、データベースの中では、皆さんが投げたクエリに対して「どの道順でデータを探しに行くか」を、プランナという司令塔が必死に考えています。今日は、その司令塔が「インデックス(索引)」を使うか「シーケンシャルスキャン(全件舐め)」をするか、どうやって決めているのか、その裏側を覗いてみましょう。
—
図書館の本探しで考えてみよう
例えば、あなたが巨大な図書館で「特定の1冊の本」を探すとします。
1. インデックスを使う場合:
入り口にある「検索機(インデックス)」で本の場所(棚番号)を調べてから、その棚へ一直線に向かう。
2. シーケンシャルスキャン(全件スキャン)をする場合:
入り口から順に、端から端まで全ての棚を歩き回って、お目当ての本を探す。
普通に考えれば「検索機を使ったほうが早い」ですよね? でも、もし探している本が「図書館にある本全部」だったらどうでしょう? 検索機を引く時間が無駄になるので、入り口から順に歩いていった方が早いかもしれません。
PostgreSQLもこれと全く同じことをやっているんです。
プランナが「コスト」を計算する仕組み
PostgreSQLには「プランナ」という頭脳がいます。彼はクエリを実行する前に、「どっちのルートで行くのが一番コスト(時間と手間)がかからないかな?」と計算しています。
実は、この「コスト」を判断する基準には、こんな要素が関わっています。
- データの量: テーブルにどれだけのデータが入っているか。
- データの偏り: 特定の値ばかり入っていないか。
- インデックスの効率: そのインデックスを使えば、何%くらいのデータを絞り込めるか。
プランナは、これらの統計情報を元に「これくらいのデータ量なら、インデックスを引くより、全部見ちゃったほうが速いな!」と判断する「閾値(しきいち)」を持っているんです。
怖いのは「勘違い」
ここで一つ、現場でよくある落とし穴の話をします。
プランナは完璧ではありません。彼が使っている「統計情報(テーブルの状態をまとめたメモ)」が古くなっていると、とんでもない勘違いをすることがあるんです。
- 「テーブルには100件しかデータがないはずだから、全件スキャンでいいや」と判断。
- 実際には、昨日大量のデータが追加されて100万件になっていた!
- 結果: 100万件を全件スキャンして、クエリがいつまで経っても終わらない……。
これが「統計情報の鮮度が落ちている」ことによる悲劇です。
私たちにできる「心遣い」
では、どうすればいいのでしょうか? 難しい設定をいじる前に、まずはこの2つを覚えておいてください。
1. 「統計情報を最新に保つ」こと:
PostgreSQLには「ANALYZE」というコマンドがあります。これを定期的に実行するだけで、プランナは最新の状況を知ることができ、適切なルートを選んでくれるようになります。
2. 「やりすぎない」こと:
「インデックスを作れば速くなる!」と思って無闇に作りすぎるのも考えものです。インデックスが増えると、データを更新するたびにそのインデックスも書き換えなきゃいけないので、逆にシステムが重くなってしまうこともあります。
—
最後に
データベースのチューニングと聞くと難しく聞こえますが、要は「効率の良い探し方を選ばせてあげること」です。
プランナは、皆さんの味方です。でも、たまに情報の行き違いでヘマもします。そんな時は「最近の状況はこうだよ!」とANALYZEコマンドで教えてあげてください。そうすれば、きっとまた元気に、最速のルートを見つけてくれるはずですよ。
それでは、また次回の記事でお会いしましょう!データベースライフを楽しんでくださいね。
コメント