2013-05-27 7 views
27

これはSQL Server 2008 R2に関する質問です。一時テーブルとサブセレクトのパフォーマンスが大きく異なる理由

私はDBAではありません。私はJava開発者で、時々SQLを書く必要があります。 (主にコードに埋め込まれています)。私はここで何か間違っているかどうかを知りたいのですが、もしそうなら、私はそれが再び起こるのを避けるために何ができるのですか。

Q1:

SELECT something FROM (SELECT * FROM T1 WHERE condition1) JOIN ... 

Q1 14を備え

を結合

Q2は1つの例外を除いて、Q1と同じです。 (SELECT * FROM T1 WHERE condition1)が実行され、一時表に格納されます。

これは相関サブクエリではありません。

Q2:再び

SELECT * INTO #tempTable FROM T1 WHERE condition1 
SELECT something FROM #tempTable JOIN ... 

、14が合流します。

Q2(両方のクエリを組み合わせた)が2秒かかっている間に、Q1が> 2分を要した(それを数回試して、役割を演じるのを避けるために)。何がありますか?

+3

私の推測では、「SELECT * FROM T1 WHERE condition1'の推定行数は非常に不正確です。これを '#tempTable'に具体化すると、SQL Serverは返される行の数を正確に知ることができます。両方の実際の実行計画のXMLバージョンを投稿できますか? –

答えて

40

サブクエリを使用することをお勧めしませんなぜ?

データベースオプティマイザは、使用しているデータベースに関係なく、サブクエリを使用して常にそのようなクエリを適切に最適化できるとは限りません。この場合、オプティマイザの問題は、結果セットを結合する正しい方法を選択することです。 2つの結果セットを結合するアルゴリズムはいくつかあります。アルゴリズムの選択は、一方と他方の結果セットに含まれるレコードの数によって異なります。 2つの物理テーブルを結合する場合(サブクエリは物理テーブルではありません)、データベースは2つの結果セットのデータ量を使用可能な統計値で簡単に判断できます。結果セットの1つがサブクエリである場合、それが返すレコードの数を理解することは非常に困難です。この場合、データベースは誤った結合プランを選択する可能性があるため、クエリのパフォーマンスが大幅に低下します。

一時テーブルを使用してクエリを書き換えることは、データベースオプティマイザを簡素化することを目的としています。リライトされたクエリでは、ジョインに参加するすべての結果セットは物理テーブルになり、データベースは各結果セットの長さを簡単に決定します。これにより、データベースはすべての可能なクエリプランの中で最も速く保証されたものを選択することができます。さらに、データベースは条件に関係なく正しい選択を行います。一時テーブルを使用した書き直しクエリは、どのデータベースでもうまく機能しますが、これはポータブルソリューションの開発において特に重要です。さらに、書き換えられたクエリは、読みやすく、理解しやすく、デバッグするのが簡単です。

一時テーブルを使用してクエリを書き換えると、一時的なテーブルの作成という追加の費用がかかり、パフォーマンスが低下することがあります。データベースがクエリプランの選択と誤解されない場合、古いクエリは新しいクエリよりも速く実行されます。しかし、この減速は常に無視されます。通常、一時テーブルの作成には数ミリ秒かかります。つまり、遅延はシステム性能に大きな影響を与えることはできず、通常は無視することができます。

重要!一時テーブルのインデックスを作成することを忘れないでください。インデックスフィールドには、結合条件で使用されるすべてのフィールドが含まれている必要があります。

+1

SQL Serverクエリエンジンは一時的にテンポラリテーブルを作成します。上記で指定した理由は必ずしも真ではありません.ITはインデックス、断片化、統計などの多くの要因に依存します。 – AnandPhadke

+2

テンポラリテーブルにインデックスを作成するとクエリのパフォーマンスが向上します。 – nirupam

+1

あなたは答えがかなり間違っていると間違っている、一時テーブルを作成する場合は、特定のケースでのみ考慮する必要があります:http://stackoverflow.com/questions/42772428/should-all-sub-queries-be-replace-with-temporary-tables ?noredirect = 1#comment72660694_42772428 – Arvand

8

ここでは、インデックス、実行計画などに取り組むべきことがたくさんあります。テストと比較結果は、行く方法です。

通常の容疑者、索引を見ることができます。実行計画を見て比較してください。 WHERE句が正しいものを使用していることを確認してください。 JOINsのインデックスを使用していることを確認してください。

これらの回答は、あなたに大いに役立つでしょう。

関連する問題