【入門編】 式評価の最適化 – PostgreSQL

こんにちは!データベースの世界へようこそ。
普段、PostgreSQLを触っていて「なんだかクエリの動きがもっさりしているな……」と感じることはありませんか?

今日は、そんな悩みを解決するためのちょっとした「賢い工夫」についてお話しします。難しそうな言葉はなるべく使わずに、日常の買い物に例えて解説していきますね。

—

「毎回計算する」のは、もうやめましょう

想像してみてください。あなたは今、スーパーで買い物をしています。
目の前には「1個100円のリンゴを5個買う」という注文書があるとします。

このとき、もしあなたが「100×5」という計算を、リンゴをカゴに入れるたびに行っていたらどうでしょう?

  • 1個目を入れるとき:「100×5は…500!」
  • 2個目を入れるとき:「100×5は…やっぱり500!」
  • ……これを5回繰り返す。

正直、めちゃくちゃ非効率ですよね。一度「500円だ」と分かったら、その答えをメモしておけばいいだけのことです。

データベースの世界でも、これと全く同じことが起きています。

PostgreSQLの「定数畳み込み」という魔法

PostgreSQLには、人間が書いた複雑な式を、実行前に「あ、これ答えは決まってるな」と判断して、あらかじめ計算してスッキリさせてくれる機能があります。これを「定数畳み込み(Constant Folding)」と呼びます。

例えば、クエリの中に `WHERE price > 100 24` と書いたとします。
PostgreSQLは気を利かせて、「あ、これは `WHERE price > 2400` ってことね」と、実行する前にあらかじめ計算を終わらせてくれるんです。

でも、この魔法は「いつも完璧」とは限りません。

—

避けるべき「無駄な計算」の例

データベースが賢いとはいえ、書き方によっては「計算しなくてもいいこと」を、あえて何度も計算させてしまうケースがあります。特に注意したいのが、「関数」の使い方です。

1. 毎回呼び出される「お節介な計算」

例えば、こんなクエリはどうでしょう?

— よくある「やってしまいがちな」書き方
SELECT FROM orders
WHERE created_at > NOW() – INTERVAL ‘1 day’;

このクエリは、「今この瞬間から24時間前までのデータ」を取ってきます。一見普通に見えますよね。
でも、もしこのテーブルに100万件のデータがあったら、PostgreSQLは「今この瞬間は何時何分か?」という計算を、100万回繰り返す可能性があるんです。

「たった1回の計算でしょ?」と思うかもしれませんが、クエリが複雑になればなるほど、この小さな「チリ」が積み重なって、パフォーマンスを大きく落とす原因になります。

2. どう改善すればいい?

答えは簡単です。計算は「一度だけ」にして、あとはそれを代入する。これだけでOKです。

アプリケーション側(プログラム側)で、「今の時刻から1日前の時刻」を計算してから、その結果をクエリに渡してあげましょう。

— プログラム側で計算した時刻を『2023-10-27 10:00:00』だとすると
SELECT FROM orders
WHERE created_at > ‘2023-10-27 10:00:00’;

これなら、データベースは余計な関数計算をせず、単純に数字を比較するだけで済みます。結果として、クエリは爆速になります。

—

最後に:完璧を目指さなくていいんです

ここまで読んで、「じゃあ、どんな時も計算式を書いてはいけないの?」と不安になったかもしれませんね。でも、そんなことはありません。

大切なのは、「データベースに余計な仕事をさせていないかな?」と一歩立ち止まって考えることです。

  • 毎回同じ結果になる計算を、クエリの中で繰り返していないか?
  • その計算は、プログラム側で先に済ませられないか?

この視点を持つだけで、あなたの書くSQLは劇的に美しく、そして速くなります。
まずは、今書いているクエリの中で「これ、毎回計算しなくても結果は同じじゃない?」という箇所を探すところから始めてみてください。

データベースチューニングの世界は、こうした小さな工夫の積み重ねです。ぜひ、楽しみながら最適化してみてくださいね!

それでは、また次回の記事でお会いしましょう!

コメント

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