やあ、こんにちは!今日もデータベースの世界を楽しんでいますか?
PostgreSQLを使っていて、「あれ?さっきまでサクサク動いていたクエリが、急に遅くなったぞ?」なんて経験、一度はありますよね。そんな時、実は「統計情報」というデータベースの「勘違い」が原因だったりするんです。
今回は、その中でも意外と見落とされがちな「NULL率(null_frac)」という、ちょっと地味だけど実はとっても大事な数字についてお話ししますね。
—
「NULL」って、そもそも何者?
データベースにおける「NULL」は、いわば「空っぽ」や「未入力」のこと。
例えば、皆さんのスマホの連絡先アプリを想像してみてください。「名前」や「電話番号」は全員が持っているかもしれませんが、「ニックネーム」や「FAX番号」は空欄の人も多いですよね。この「空欄」の状態こそが、データベースで言うところの「NULL」です。
クエリの迷子を救う「NULL率」の正体
さて、本題の「NULL率(null_frac)」です。これは、その列の中に「どれくらいの割合で空欄が含まれているか」を表すパーセンテージのことです。
なぜこれが大事なのか。PostgreSQLはクエリを実行するとき、事前に「どの順番でデータを読みに行けば一番速いかな?」という計画を立てます。これを「実行計画」と呼ぶのですが、この計画を立てる時に、PostgreSQLは統計情報を見てこう考えます。
- 「この列、ほとんどがNULL(空欄)だな。ということは、`IS NOT NULL`で検索したら、該当するデータはごくわずかだ。それなら、インデックスを使って一気に探しに行こう!」
- 「おっと、この列はほとんどデータが入っているぞ。それなら、わざわざインデックスを使わずに、表全体を順番にチェックしたほうが速そうだな」
つまり、NULL率は、データベースにとって「どの道を通るのが一番の近道か」を判断するための重要なヒントなんです。
もし、このヒントが間違っていたら?
想像してみてください。皆さんが友だちと待ち合わせをしていて、「駅の改札前にいるよ」と聞いていたのに、実際に行ってみたらそこには誰もいなくて、実は「駅前のカフェ」にいた……なんてことがあったら、時間を大幅にロスしちゃいますよね?
データベースでも同じことが起きます。
「この列はほとんどNULLだよ」という統計情報が古くなっていて、実際にはデータがぎっしり詰まっていたらどうでしょう。PostgreSQLは「該当データは少ないはずだ!」という前提で非効率な検索ルートを選んでしまい、結果としてクエリが極端に遅くなってしまうんです。
解決策は「掃除」と「メンテナンス」
じゃあ、どうすればいいの?と不安になる必要はありません。解決策はとてもシンプルです。
PostgreSQLには、自動的に統計情報を最新の状態に保つ「オートバキューム(autovacuum)」という頼もしい機能がついています。基本的には、データベースを放置せずに運用していれば、この機能が勝手に「今のNULL率はこれくらいだよ!」と情報を更新してくれます。
ただ、もし「急激にデータが増えた」「大量にデータを削除した」といった大きな変化があった直後なら、手動で以下のコマンドを叩いてあげるのもテクニックの一つです。
ANALYZE テーブル名;
これだけで、PostgreSQLは最新の「NULL率」を再確認して、また賢い計画を立ててくれるようになります。
—
最後に:データベースと仲良くなるために
「NULL率」なんて聞くと難しそうですけど、結局のところ「データベースという優秀な部下に、最新の状況を正しく伝えてあげること」が、高速化への一番の近道なんです。
皆さんが書いたコードが期待通りに動かない時、「もしかして、今のデータ状況をデータベースは誤解しているのかも?」と疑ってみてください。そうやって「データベースの気持ち」を想像できるようになると、チューニングはもっともっと楽しくなりますよ。
それでは、また次回のブログでお会いしましょう!あなたのデータベースライフが、今日も快適でありますように。
コメント