2011-09-12 9 views
2

私は次のような状況に陥っています:サブクエリを持つIN文よりも速い項目のリストを持つIN文はなぜですか?

私は2つのレコードを選択しなければならないかなり複雑なビューを持っています。

SELECT * FROM VW_Test INNER JOIN TBL_Test ON VW_Test.id = TBL_Test.id 
WHERE VW_Test.id IN (1000,1001,1002,1003,1004,[etc]) 

これは実質的に即座に結果を返します(現在INステートメントに25個の項目があります)。しかし、私は次のクエリを使用するとき、それは本当に速く減速します。

SELECT * FROM VW_Test INNER JOIN TBL_Test ON VW_Test.id = TBL_Test.id 
WHERE VW_Test.id IN (SELECT id FROM TBL_Test) 

このクエリは、TBL_Testに25個のレコードがあり、約5秒かかります。私はTBL_Testのidにインデックスを持っています。

これがなぜ起こり、どのようにパフォーマンスを上げるのか誰でも知っていますか?

編集:私はこのサブクエリ

SELECT id FROM TBL_Test 

は即座に、同様の結果を返すことを言及するのを忘れてしまいました。

+0

「TBL_Test」の最新の統計情報はありますか?実行計画を比較して、それらの間で何が違うかを見てください。これはあなたの実際のクエリですか、それとも簡略化しましたか?サブクエリでunsargableフィルタを使用して統計推定を誤っている可能性がある場合は不思議です。 –

+0

@Kirillそのクエリはまったく同じように実行されます。 – SouthL

+0

@Martin実行計画の違いは、最初はビューをもっと早くフィルタリングすることにあるようです。サブクエリを使用すると、ビュー全体がプルアップされ、TBL_Testと結合されます – SouthL

答えて

1

サブクエリを使用する場合、データベースエンジンはまずサブクエリの結果を生成してから、何か他の処理を行うことができますが、時間がかかります。あらかじめ定義されたリストがある場合、これは起こる必要はなく、エンジンは単にそれらの値をそのまま使用することができます。少なくとも、これは私がそれを理解する方法です。

パフォーマンスを向上させる方法:サブクエリを削除します。私はあなたがこの場合IN句を必要とするとは思わない。 INNER JOINで十分です。

+0

でした。サブクエリから結果を得ることは即座に行われます。私は私の質問で言及することを忘れていた。 – SouthL

+0

@Frank 'IN'はSQL Serverの(半)結合として実装されています –

+0

@Martin Frankのポイントは、INは完全に不要であると考えています - 指定されたクエリはまったく同じものを返さなければなりませんそのWHERE句を完全に削除するだけで結果が得られます。 –

関連する問題