こんにちは!データベースの世界へようこそ。
普段、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は劇的に美しく、そして速くなります。
まずは、今書いているクエリの中で「これ、毎回計算しなくても結果は同じじゃない?」という箇所を探すところから始めてみてください。
データベースチューニングの世界は、こうした小さな工夫の積み重ねです。ぜひ、楽しみながら最適化してみてくださいね!
それでは、また次回の記事でお会いしましょう!
コメント