こんにちは!データベースの世界へようこそ。
普段、何気なくSQLを書いて「データが返ってきた!」と喜んでいるあなたも、その裏側でデータベースがどんなふうに頑張っているのか、少し気になったことはありませんか?
今日は、PostgreSQLがテーブル同士をくっつけるときに使う、一番シンプルで、でも奥が深い「ネステッドループ結合(Nested Loop Join)」についてお話ししますね。
—
そもそも「結合(ジョイン)」って何してるの?
データベースで「結合」するというのは、簡単に言えば「2つの名簿を突き合わせて、共通の項目で情報をまとめる作業」のことです。
例えば、右手に「社員名簿」、左手に「部署名簿」を持っていると想像してください。「この社員さんはどの部署に所属しているのかな?」と調べるために、社員名簿の1行目から順番に名前を見て、部署名簿の中から同じ部署を探しに行く……。
実はこれこそが、今回紹介する「ネステッドループ結合」そのものなんです。
ネステッドループ結合の動きをイメージしてみよう
このアルゴリズムの名前はちょっと堅苦しいですが、やっていることは驚くほど人間味があります。
1. 左側のテーブル(外側のループ)から、1行目を手に取る。
2. その行の情報を持って、右側のテーブル(内側のループ)の先頭から順番に、一致するデータがないか探しに行く。
3. 見つけたら「はい、これ!」と結果を記録する。
4. 右側のテーブルの最後まで探し終わったら、左側のテーブルの2行目へ戻る。
5. これを、左側のテーブルが空になるまで繰り返す。
……どうでしょう? まるで、辞書を片手に、単語帳の言葉を一つずつ調べていくような作業ですよね。
「ネステッドループ」が得意なこと、苦手なこと
この方法は、「とにかくシンプル」というのが最大の武器です。
準備運動(事前の計算やデータの並び替え)がほとんどいらないので、対象となるデータが少ないときや、検索条件がピンポイントで決まっているときは、爆速で結果を返してくれます。
でも、弱点もあります。
もし、左側のテーブルに1万行あって、右側のテーブルにも1万行あったらどうなるでしょう? 最悪の場合、1億回(1万 × 1万)も辞書をめくることになりますよね。
データが巨大になればなるほど、この「総当たり作戦」は時間がかかりすぎて、データベース君もヘトヘトになってしまうんです。
こんなときは要注意!
- 結合するテーブルがどちらも巨大なとき
- 検索するための「目印(インデックス)」が右側のテーブルに設定されていないとき
最後に:データベースと仲良くなるために
「ネステッドループ」は、データが少ない場所なら最強の助っ人ですが、相手が大きくなると途端に非力になります。
もしあなたが書いたクエリが遅いな?と感じたら、PostgreSQLがこの「ネステッドループ」で頑張りすぎていないか、一度確認してみてください。もしそうなら、適切な場所にインデックスを貼るだけで、彼らは「ああ、辞書をめくらなくても、どこに何があるかすぐ分かるようになったよ!」と、見違えるような速さで結果を返してくれるようになります。
データベースのチューニングって、なんだか「片付け」に似ていると思いませんか?
どこに何があるか分かりやすく整理してあげれば、仕事はもっとスムーズに進むはず。
今日の記事が、あなたのSQLライフを少しでも楽しく、そして快適にするヒントになれば嬉しいです!また次回のブログでお会いしましょうね。
コメント