次のSQLクエリを実行すると
SELECT *
FROM A
LEFT JOIN B
ON A.foo=B.foo
WHERE A.date = "Yesterday"
WHERE
ステートメントは?の前または後に評価されますJOIN
か?
A
後の場合、からの行のみが返されるようにこのステートメントを記述するためのより良い方法は何に"Yesterday"
結合されB
ますか?
次のSQLクエリを実行すると
SELECT *
FROM A
LEFT JOIN B
ON A.foo=B.foo
WHERE A.date = "Yesterday"
WHERE
ステートメントは?の前または後に評価されますJOIN
か?
A
後の場合、からの行のみが返されるようにこのステートメントを記述するためのより良い方法は何に"Yesterday"
結合されB
ますか?
データベースによって異なります。
SQL Serverで、次のコマンドを実行します。SET SHOWPLAN_ALL ON
次にクエリを実行すると、実行時に何が起こるかがわかります。
SQLは宣言型言語であるため、「評価」の考え方は正しくありません。
ところで、クエリ実行プランを見ることができます。MySQLでは、クエリの前にキーワードdescribe
を付けて実行プランを確認します。
意味論的に:JOINの後。ただし、この場合、JOINの左側にあるため、タイミングに違いはありません。
すでにお持ちのように、「「昨日」のAの行のみがBに結合されます」。
オプティマイザーは、関係代数の等価性に応じて、操作の順序を自由に再編成できます。
これはA.date="Yesterday"のみを返し、fooで一致するものを見つけることができるBに参加します。
SELECT * FROM A
LEFT JOIN B
ON A.foo=B.foo
WHERE A.date="Yesterday"
これにより、基準に関係なくすべてのAが返され、A.date = "Yesterday"であるBに参加し、fooで一致するものが見つかります。
SELECT * FROM A
LEFT JOIN B
ON A.foo=B.foo
AND A.date="Yesterday"
クエリを満たすための操作の順序は、特定のデータベースのクエリオプティマイザの気まぐれがなぜであるかによって決まります。クエリオプティマイザは、クエリから収集できるものと、データベースに関して手元にある統計(テーブルのカーディナリティや特定のデータ分布を含む可能性があります)に基づいて、優れた「クエリプラン」(一連の操作)を作成しようとします。 。
あなたの場合、答えはあなたがA.dateに二次インデックスを持っているかどうかに依存するかもしれません
クエリの最適化はかなり豊富なトピックです。使用しているデータベースのドキュメントには、それについてもっと多くのことが書かれています。
インデックスと統計に依存します。
クエリの実行パスを表示して、最適化を適用する場所(ある場合)を決定する必要があります。
SQL Serverの場合:
一般的な経験則として、JOIN句はWHERE句の前に評価されます。
結合部分にフィルターが必要な複雑な結合の場合、結合と一緒にそれらを記述します
SELECT *
FROM A
LEFT JOIN B
ON A.Foo1 = B.Foo1
And A.Date = 'Yesterday'
OUTER JOIN C
ON B.Foo2 = C.Foo2
JOIN D
ON B.Foo3 = D.Foo3
SELECT *
FROM (SELECT * FROM A WHERE Date = 'Yesterday') A
LEFT JOIN B
ON A.Foo1 = B.Foo1
OUTER JOIN C
ON B.Foo2 = C.Foo2
JOIN D
ON B.Foo3 = D.Foo3