web-dev-qa-db-ja.com

クエリとサブクエリは、SQLエンジンによってどの順序で実行されますか?

こんにちは私はSQLテストを行い、1つの質問について疑わしい/興味があります:

SQLエンジンによって実行されるクエリとサブクエリはどのシーケンスにありますか?

答えは

  1. プライマリクエリ->サブクエリ->サブサブクエリなど
  2. サブサブクエリ->サブクエリ->プライムクエリ
  3. クエリ全体が一度に解釈されます
  4. 解釈の固定されたシーケンスはなく、クエリパーサーがオンザフライで決定します

私は最後の答えを選びました(それが他のものよりも最も信頼できると仮定しているだけです)。今好奇心:

これについてどこで読むことができ、簡単にそのすべてのメカニズムは何ですか?

ありがとうございました。

30
Igor

オプション4は終了しました。

SQLは declarative です:クエリオプティマイザーに必要なことを伝え、それを実行する最良の方法(時間/「コスト」など)が機能します。これは、統計、データ分布、行数、並列処理、および神が他に何を知っているかに応じて、外見上同じクエリとテーブルでは異なる場合があります。

つまり、決まった順序はありません。しかし、「オンザフライ」ではない

同一のサーバー、スキーマ、クエリ、データでも実行プランが異なる

17
gbn

答え4は正しいと思います。いくつかの考慮事項があります。

サブクエリのタイプ-相関しているかどうか。考慮してください:

SELECT *
FROM   t1
WHERE  id IN (
             SELECT id
             FROM   t2
            )

ここでは、サブクエリは外部クエリに関連付けられていません。 t2.idの値の数がt1.idと比較して少ない場合は、最初にサブクエリを実行し、結果をメモリに保持してから、t1またはt1.idのインデックスをスキャンして、キャッシュされた値。

しかし、クエリが次の場合:

SELECT *
FROM   t1
WHERE  id IN (
             SELECT id
             FROM   t2
             WHERE  t2.type = t1.type
            )

ここでサブクエリは相関しています-t1.typeが既知でない限り、サブクエリを計算する方法はありません。 t1.typeの値は外部クエリの行ごとに異なる可能性があるため、このサブクエリは外部クエリの行ごとに1回実行できます。

この場合も、RDBMSは非常に賢く、t2.typeに可能な値がほんの少ししかないことに気付くでしょう。その場合、サブクエリを1回実行するコストが各行に対して実行するコストよりも安くなると推測できる場合は、無相関サブクエリに使用されるアプローチを使用できます。

25
Roland Bouman

これらのトピックについて読みたい場合は、「SQL Server 2008の内部:T-SQLクエリ」を入手してください。 SQL Serverで論理的および物理的にクエリを処理する方法に関する2つの専用の章があります。

1
Frank Kalis

SQLエンジンは、(サブ)クエリが実行される順序を最適化しようとします。それを決める部分をクエリオプティマイザといいます。クエリオプティマイザーは、各テーブルの行数、インデックスを持つテーブル、およびどのフィールドにあるかを認識しています。その情報を使用して、最初に実行する部分を決定します。

1

通常はDBMSに依存しますが、... 2番目の答えの方がより適切であると思います。プライムクエリは通常、サブクエリの結果なしでは計算できません。

0
Adelf