【実務・中級編】 データ検索(SELECT)の基本 – PostgreSQL

やあ。最近、PostgreSQLを触り始めたんだって?いいチョイスだね。

現場でバリバリ動いているシステムを見ていると、結局のところ「いかに効率よく、意図通りのデータをDBから引き出すか」がエンジニアの腕の見せ所だったりする。ORM(Object-Relational Mapping)も便利だけど、裏側でどんなSQLが走っているのかを知っておかないと、いざという時に泣きを見ることになるからね。

今日は、SQLの基本中の基本、`SELECT`文を深掘りしてみよう。教科書的な構文解説だけじゃなく、実務でハマりやすいポイントも交えて話すよ。

—

基本の型:SELECT文の「お作法」

まずは基本の構文を整理しよう。現場で書くSQLは、大体この順番で構成されることが多いね。

SELECT column1, column2
FROM table_name
WHERE condition
ORDER BY column_name [ASC|DESC]
LIMIT count OFFSET start;

これ、なんとなく書いていないかな? 実はデータベース(PostgreSQL)は、この順番で処理をしているわけじゃないんだ。「FROM → WHERE → SELECT → ORDER BY → LIMIT/OFFSET」 という順序で脳内変換できるようになると、クエリのチューニングが一気に上手くなるよ。

1. WHEREで「無駄なデータ」を拾わない

「とりあえず全件取ってからプログラム側でフィルタリングすればいいや」……これ、新人時代にやりがちだけど、NGだ。データベースは「絞り込み」のプロなんだから、極力`WHERE`句で必要な行だけに絞ろう。

— 悪い例:全件取得してアプリ側で条件分岐
— 良い例:DB側で最初から絞る
SELECT name, email
FROM users
WHERE status = ‘active’ AND created_at >= ‘2023-01-01’;

PostgreSQLなら、この`WHERE`句でインデックスが効くかどうかを`EXPLAIN ANALYZE`で確認するのが癖になると最高だね。

2. ORDER BYで「並び」を制御する

「並び順なんて適当でいいや」と思うかもしれないけれど、実はここが一番トラブルの種になりやすい。
`ORDER BY`を省略すると、DBは「物理的に速く読み取れる順」でデータを返すから、実行するたびに結果の順番が変わる可能性があるんだ。

  • ページネーションする時は必須: `LIMIT`と`OFFSET`を使う時は、必ず`ORDER BY`で順序を確定させよう。順序が不安定だと、ページ送りをした時に同じデータが重複したり、逆に表示されなかったりという悪夢を見る羽目になるよ。

3. LIMITとOFFSETで「ページング」を攻略する

Webアプリケーションを作るなら、リスト表示のページネーションは避けて通れない。

— 2ページ目(1ページ10件)を取得する場合
SELECT FROM users
ORDER BY id
LIMIT 10 OFFSET 10;

ここで一つだけ、先輩からのアドバイス。
`OFFSET`は、値が大きくなればなるほどパフォーマンスが落ちるんだ。DBは「10000個飛ばして次の10個を取る」ために、最初の10000個を一度読み込む必要があるからね。数万件以上の大規模なテーブルでページングをする時は、`OFFSET`を使わずに「カーソルページング(前のページの最後のIDより大きいものを取得する、といった手法)」を検討するのがプロの技だ。

—

現場で役立つ「ちょっとしたコツ」

最後に、実務で「おっ、こいつ分かってるな」と思われるポイントを一つ。

カラム名は省略しない

`SELECT ` を使いたくなる気持ちはわかる。でも、カラムの構成が変わった時にアプリ側で予期せぬエラーが出ることがあるし、不要なカラムまで読み込むとメモリの無駄遣いになる。必要なカラムだけを明示的に書く。これが保守性の高いコードを書くための鉄則だよ。

—

最後に:SQLは「対話」だと思おう

SQLを書くときは、データベースという優秀な相棒に対して「この条件で、この順番で、これだけちょうだい」と具体的に指示を出しているんだとイメージしてみて。

PostgreSQLは非常に強力で、正しく使えば驚くほど高速に応えてくれる。最初は基本を丁寧に押さえるだけで十分。まずは今日の`SELECT`文から、自分の手でいろいろ試してみてほしい。

もしクエリを書いていて「これ、もっと速くならないかな?」と迷ったら、いつでも聞いてくれ。また次回の記事で会おう!

コメント

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