2009-07-01 4 views
0

「WHERE IN(SELECT 1 FROM MyTable)」のような節が高速であるか、 。誰もがそれを持っている場合、私は、答えを知りたいSqlServer 2005(または一般に任意のRDBMS)のIN()とEXISTS()との比較

SELECT * FROM Orders 
WHERE ShipRegion = 'WA' AND EXISTS (
    SELECT EmployeeID FROM Employees AS Emp 
    WHERE Emp.EmployeeID = Orders.EmployeeID) 

それとも

SELECT * FROM Order 
WHERE ShipRegion = 'WA' AND EmployeeID IN (
    SELECT EmployeeID FROM Employees AS Emp 
    WHERE Emp.EmployeeID = Orders.EmployeeID) 

:(MyTableとから1を選択)EXISTS

のは、SqlServerのドキュメントからのクエリを使用してみましょうWHEREしかし、私は本当に私がどのようにテストするのか知りたいです私はSqlServer 2005で自分自身のためにtを使用しています。(私はSqlServerのnoobです)

ありがとう!

答えて

2

、次のことができます。 もなり、実行計画を比較し、両方のクエリとCtrlキーを押しながらLをハイライト表示し、あなたの両方が

を照会実行し

SET STATISTICS IO ON 
SET STATISTICS TIME ON 

を実行し、実際の実行コストを比較計画を参照してください。ほとんどの場合、同じ計画が表示されます。

+0

ありがとうございます!これは、私が探していた質問のもう一つの部分でした。私はこのようなものを測定する方法がなければならないことを知っていましたが、私はどのようにこのことを知りませんでした。今私がやります! – EoRaptor013

1

またIN場合にWHERE句を削除することができます:

SELECT * FROM Orders 
WHERE ShipRegion = 'WA' AND EmployeeID IN (SELECT EmployeeID FROM Employees) 

クエリオプティマイザは両方のクエリに対して同じ実行計画を生成することができるはずです。私はより読みやすいものを選んでいます。自分のために参照するには

+0

実際、これは良い例ではないかもしれません。 OrdersからEmployeesへの外部キー制約により、テストの必要性が排除されます。 –

+0

@ジョン:確かに。もちろん、私はそれについて何の前提もしていませんでした。 –

+0

うーん...私は、これは()バックにいるかどうかに行く、それは最初の一致を見つけたときに停止しますね。もしそうなら、それは私の2つの例の間に違いがないことを示唆します。そうでない場合はOTOH、その後も、WHERE句なしで、(EXISTS)なし、高速になりますか? お返事ありがとうございます。 – EoRaptor013

1

SQLサブクエリ、それが共同関連していると、JOINに変更することができたものと同一であなたが探している答えを与えることはありませんが。

一般に、EXITTS()は最初の行が見つかるとそれ以上の関係を見つけることなく結果を返すので、IN()はそれが完了するまで の行を見つけなければならないので、

ので

SELECT * FROM Orders 
WHERE ShipRegion = 'WA' AND EXISTS (
    SELECT 'x' FROM Employees AS Emp 
    WHERE Emp.EmployeeID = 42) 

は、JOIN INNERを使用し

SELECT * FROM Order 
WHERE ShipRegion = 'WA' AND EmployeeID IN (
    SELECT EmployeeID FROM Employees AS Emp 
    WHERE Emp.EmployeeID = 42) 
+1

一致が見つかったらINを続行する必要がありますか?明らかにINは必要ではありませんが、なぜINですか? –

+0

分析をお寄せいただきありがとうございます!これは、私が探していたことのほとんど、特に理論的または技術的な部分(Existsは最初のヒット後に停止します)です。あなたはMSDNの本のオンラインでこれを言及すると思います。 – EoRaptor013

+0

ああ、私の例は必然的に良いものではありません。私は頭の上から現実的な何かを考え出すことができなかったので、私はMSのEXISTS()のサンプルコードをちょうど打ちました。 – EoRaptor013

2

前に終了しなければならないことは、サブクエリよりも高速になります:

SELECT * 
    FROM Order o 
INNER JOIN Employees e ON o.EmployeeID = e.EmployeeID 
WHERE ShipRegion = 'WA' 

または特定の基準に:

SELECT * 
    FROM Order o 
INNER JOIN Employees e ON o.EmployeeID = e.EmployeeID 
WHERE ShipRegion = 'WA' 
    AND e.EmployeeID = 42 
関連する問題