48

SQL Server 2008 R2 についての質問です

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

Q1:

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

第 1 四半期には 14 件の参加がありました

Q2 は Q1 と同じですが、1 つの例外があります。(SELECT * FROM T1 WHERE condition1) が前に実行され、一時テーブルに格納されます。

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

Q2:

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

ここでも 14 人が参加します。

今私を困惑させているのは、Q1が2分以上かかったことです(キャッシングを避けるために数回試しました)が、Q2(両方のクエリを組み合わせる)は2秒かかりました!!! 何を与える?

4

2 に答える 2

63

サブクエリの使用が推奨されないのはなぜですか?

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

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

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

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

于 2013-05-27T09:26:44.187 に答える
11

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

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

これらの答えは確かにあなたを大いに助けます。

于 2013-05-27T07:24:35.117 に答える