なぜかクエリが遅い……そんな時の「魔法のメガネ」の話
こんにちは!データベースの世界に飛び込んで、日々のデータ操作に奮闘している皆さん。
PostgreSQLを使っていると、ふとこんな場面に出くわしませんか?
「さっきまでサクサク動いていたはずのクエリが、急に重たくなった……」
「特定の処理だけ、どうしてこんなに時間がかかるんだろう?」
そんなとき、多くの人は「インデックスが足りないのかな?」「SQLの書き方が悪いのかな?」と悩みますよね。もちろんそれも正解ですが、実は「ディスクとのやり取り」で足止めを食らっていることが非常に多いんです。
今日は、そんな「見えないボトルネック」を可視化してくれる、PostgreSQLのちょっと地味だけど最高に頼れる機能`track_io_timing`についてお話しします。
—
「料理」で例えると分かりやすい?
データベースの動きを、レストランのキッチンに例えてみましょう。
- メモリ(RAM):すぐ手の届くところにある「まな板の上」。ここにある食材なら、包丁で切るだけですぐ調理できますよね。
- ディスク(HDD/SSD):キッチンから遠く離れた「地下の貯蔵庫」。わざわざ階段を降りて、食材を取りに行かなければなりません。
クエリが遅いとき、私たちはつい「料理の手順(SQLの書き方)」ばかりを見直してしまいがちです。でも、もし原因が「地下の貯蔵庫への往復が多すぎて、移動だけでヘトヘトになっている」ことだとしたら、いくら料理の腕を上げても改善しませんよね。
この「貯蔵庫まで往復するのに、一体どれだけの時間を使っているのか?」を教えてくれるのが、`track_io_timing`という設定なんです。
—
`track_io_timing` をオンにすると何が起きる?
通常、PostgreSQLは「どのデータがどこにあるか」までは教えてくれますが、「それを取りに行くのに何ミリ秒かかったか」までは記録してくれません。
この設定を有効にすると、PostgreSQLはまるで優秀な秘書のように、クエリが走るたびに「ディスクへの往復時間」をストップウォッチで計ってくれるようになります。
これにより、こんなことが分かるようになります。
- 「この処理、実行時間は5秒だけど、実はそのうち4秒をディスクとの往復に使っているな」
- 「ということは、クエリの書き方を変えるより、ストレージを高速化するか、メモリに乗るようにキャッシュを調整した方が早そうだな」
—
どうやって設定するの?
設定は驚くほど簡単です。PostgreSQLの設定ファイル(`postgresql.conf`)を開いて、以下の項目を探してみてください。
track_io_timing = on
もし「off」になっていたら「on」に変えて、データベースを再読み込み(リロード)するだけ。たったこれだけで、あなたのデータベースには「I/Oの時間を計る魔法のメガネ」が装着されます。
※ちなみに、ごくわずかにCPUの負荷は増えますが、現代のサーバーならほとんど無視できるレベルです。安心してオンにしてくださいね。
—
計測した後はどうすればいい?
設定をオンにした後、`pg_stat_statements`という拡張機能などを使ってクエリの統計を見てみてください。すると、今まで見えなかった「IO_READ_TIME」や「IO_WRITE_TIME」といった数字が浮かび上がってきます。
この数字を見て、「お、ここはディスクアクセスが異常に多いぞ」と気づくことができれば、こっちのものです!
- もっとメモリを増やして、頻繁に使うデータをメモリ上に置いてあげる
- インデックスを貼って、余計なデータを読み込まないようにする
- ディスクそのものを高速なものに替える
こんなふうに、「勘」ではなく「データ」に基づいたチューニングができるようになります。これこそが、脱・初心者への大きな一歩です。
—
最後に
データベースのチューニングって、最初は難しく感じるかもしれません。でも、一つひとつ「なぜ遅いのか」という理由を解き明かしていく作業は、まるで探偵のようなワクワク感がありますよね。
`track_io_timing`は、そんなあなたの捜査を助けてくれる強力な相棒です。ぜひ皆さんの開発環境でもオンにして、その威力を体験してみてください。
「分からない」を「数字で理解する」に変えるだけで、エンジニアとしての視界はぐっと広がりますよ。それでは、また次回の記事でお会いしましょう!
コメント