質問
私の質問はこれに似ています SQL ORDER OF OPERATIONS しかし、少しひねりを加えているので、尋ねるのは公平だと思います。
Teradataを使用しています。そして、私は2つのテーブルを持っています: table1
, table2
.
table1
あるだけです id
桁。
table2
次の列があります。 id
, val
私は間違っているかもしれませんが、これらの2つの声明は同じ結果をもたらすと思います。
ステートメント1。
SELECT table1.id, table2.val
FROM table1
INNER JOIN table2
ON table1.id = table2.id
WHERE table2.val<100
ステートメント2。
SELECT table1.id, table3.val
FROM table1
INNER JOIN (
SELECT *
FROM table2
WHERE val<100
) table3
ON table1.id=table3.id
私の質問は、クエリオプティマイザーが十分に賢くなるのかということです
- 最初に句を実行してから、後でステートメント1に参加します
- ステートメント2では表3が実際には必要ないことを知ってください
私はSQLがかなり初めてなので、何か誤解している場合は教育してください。
解決
これは、多くの多くのもの(テーブルサイズ、インデックス、キーディストリビューションなど)に依存します。実行計画を確認するだけです。
どのデータベースを言っているのではありませんが、ここにいくつかの方法があります。
mysql説明
SQL Server Set ShowPlan_all(transact-sql)
Oracleは計画を説明します
Teradataで説明されているものは何ですか?
Teradataは、視覚的な説明とXMLプランの記録とより速く計画をキャプチャして比較します
他のヒント
問題のテーブルの統計とインデックスの可用性に応じて、クエリはオプティマイザーのメカニズムを書き直すことができます。 Table2
レコード用 val < 100
スキャン前 Table1
.
特定の状況では、データの人口統計に基づいて、参加、インデックス、統計に基づいて、オプティマイザーは、それがすべきだと感じたときにクエリ計画の記録を排除していないことがわかります。例のような派生テーブルがある場合でも。派生テーブルにグループを配置するだけで、派生テーブルの処理をオプティマイザーに強制することができます。オプティマイザーは、例の2つのテーブル間の結合を解決することを検討する前に、集計によりグループを解決する義務があります。
SELECT table1.id, table3.val
FROM table1
INNER JOIN (
SELECT table2.id, tabl2.val
FROM table2
WHERE val<100
GROUP BY 1,2
) table3
ON table1.id=table3.id
これは、標準的なアプローチがコードを介してこれを実行することであると言うことではありません。これは通常、私の最後の手段の1つであり、計画で十分に早期に無関係なレコードを排除しないクエリプランがあり、あまりにも多くのデータがスキャンされ、さまざまなスプールファイルを介して運ばれます。これは、そのような状況に遭遇したときにツールキットに入れることができるテクニックです。
クエリの書き換えメカニズムは、あるリリースから次のリリースに継続的に更新されており、その仕組みに関する詳細は SQLトランザクション処理マニュアル Teradata 13.0の場合。
何かが足りないのでなければ、なぜTable1が必要なのですか?
テーブル2をクエリするだけです
Select id, val
From table2
WHERE val<100
または、テーブル1の行をフィルターとして使用していますか?つまり、Table1は、Table2のIDSのサブセットのみをcopntainしていますか??
もしそうなら、これも機能します...
Select id, val
From table2
Where val<100
And id In (Select id
From table1)
しかし、あなたの質問に答えるために、はい、クエリオプティマイザーは、論理的な指示を物理的な結果に変換するために必要な手順を実行するための最良の順序を把握するのに十分なインテリジェントでなければなりません。データベースが各テーブルに維持する編集された統計を使用して、ディスクiOSと処理コストを最小限に抑えるために、操作を実行する順序としてWekllとして、何をすべきか(どのようなタイプのJoin Logicを使用するか)を決定します。
Q1。最初に句を実行してから、後でステートメント1に参加します
問題は、内部結合の順序を切り替えた場合、つまりtable2内側結合table1を切り替えると、準備段階で結合操作の前に句を処理できる場所を推測します。ただし、元のクエリを変更しなくても、Optimizerは注文を切り替えることができるはずです。結合操作が行全体をフェッチすると高すぎると思われる場合、最初に適用されます。ただ私の推測。
Q2。ステートメント2では表3が実際には必要ないことを知ってください
Teradataは、派生テーブルが必要であるような方法で2番目のクエリを解釈するため、テーブル3の操作を処理し続けます。