結合処理


あるSQLクエリがバーに入ったら、
そこには2つのテーブルがあった。
彼はそこに近づいて、こう尋ねた。
「君達、ジョインしてもいいかい?」

— 作者不詳

結合は、正規化されたモデルを、特定の目的を満たした非正規化された モデルに変換する処理です。結合処理は、分散したデータの断片をまとめる処理 なので、ディスクシークのレイテンシに特に敏感です。適切なインデックスを作る ことは、レスポンスタイムを短くするために、ここでも最適な解決策になります。 正しいインデックスがどんなものであるかは、そのクエリに対して、3つの 一般的な結合アルゴリズムのどれが使われるかによって決まります。

このウェブサイトにぴったりのカップは僕たちのショップにあります。
#見た目もいい感じだし、ここでの僕の仕事を支えてくれています

ただ、どの結合アルゴリズムにも共通することがあります。それは、 どの場合でも、同時に処理できるのは2つのテーブルまでということです。 つまり、3つ以上のテーブルを扱うSQLクエリは、まず最初に2つのテーブルを 結合して中間テーブルを生成し、それからそれを次のテーブルと結合し…と いう処理を繰り返すのです。

中間結果のパイプライン化

中間結果を見れば結合のアルゴリズムがよく分かるのですが、だからと 言って、それを目に見える形にしなければならないということではありません。 次に続く処理の前に、最初の結合の結果を保存しておく必要がある、という だけのことです。そのためデータベースは、メモリを節約するためパイプライン化を 行います。つまり、中間テーブルの各行はすぐに パイプライン化されて次の結合処理に渡され、これに よって中間結果の全体を保存する必要がないようにしているのです。

結合の順序は最終的な結果には関係ありませんが、パフォーマンスには 影響を及ぼします。オプティマイザは全ての結合順序のパターンを評価して、 最適なものを選びます。これはつまり、複雑な文を最適化することは、 やり方によってはパフォーマンス問題につながりかねないことを表します。 結合するテーブルが増えれば、評価しなければならない実行計画のパターンも増えます。 数学的に言えば、これはn! (階乗)で増加して いきます。なお、バインドパラメータを使って いる時には、この問題の影響を受けません。

重要

文が複雑になればなるほど、バインドパラメータを使う重要性が増します。

バインドパラメータを使わないのは、毎回プログラムをコンパイル し直すようなものです。

Photo of Markus Winand
Markus Winand氏は、開発者がSQLパフォーマンスを改善するお手伝いをしています。 彼は、SQL Performance Explainedの 著者でもあり、出張トレーニングhttp://winand.at/での リモート講義も 行っています。