1

結合したいテーブルが2つあり、どちらも結合しようとしている列にインデックスがあります。

QUERY 1

SELECT * FROM [A] INNER JOIN [B] ON [A].F = [B].F;

クエリ2

SELECT * FROM (SELECT * FROM [A]) [A1] INNER JOIN (SELECT * FROM B) [B1] ON [A1].F=[B1].F

最初のクエリは明らかにインデックスを利用しますが、2番目のクエリはどうですか?括弧内の2つのselectステートメントが実行された後、結合が発生しますが、インデックスはほとんど新しいテーブルであるため、クエリの高速化には役立たないと思います。

4

4 に答える 4

5

クエリは、あなたが提案するほど文字通りには実行されません。内部クエリが最初に実行され、次にそれらの結果が外部クエリと結合されます。オプティマイザーはクエリを受け取り、さまざまな結合順序、インデックスの使用法などを通じてデータを取得するためのさまざまな方法を検討し、十分に最適であると思われる計画を立てます。

両方のクエリを実行してそれぞれの実行プランを見ると、まったく同じクエリを使用していることがわかると思います。

同じ概念の簡単な例を次に示します。スキーマを次のように作成しました。

CREATE TABLE A (id int, value int)
CREATE TABLE B (id int, value int)

INSERT INTO A (id, value)
VALUES (1,900),(2,800),(3,700),(4,600)

INSERT INTO B (id, value)
VALUES (2,800),(3,700),(4,600),(5,500)

CREATE CLUSTERED INDEX IX_A ON A (id)
CREATE CLUSTERED INDEX IX_B ON B (id)

そして、あなたが提供したようなクエリを実行しました。

SELECT * FROM A INNER JOIN B ON A.id = B.id 
SELECT * FROM (SELECT * FROM A) A1 INNER JOIN (SELECT * FROM B) B1 ON A1.id = B1.id 

生成された計画は次のようになりました。

ここに画像の説明を入力してください

ご覧のとおり、どちらもインデックスを利用しています。

于 2012-07-12T20:13:37.373 に答える
4

SQL Serverクエリオプティマイザーは、クエリ2が実際にはクエリ1と同じであり、同じインデックス付きアプローチを使用していることを検出できる可能性が高くなります。

これが発生するかどうかは、テーブルの設計、テーブルの統計、クエリの複雑さなど、多くの要因によって異なります。確実に知りたい場合は、SQLServerクエリアナライザに実行プランを表示させてください。始めるのに役立つリンクは次のとおりです。

于 2012-07-12T20:13:02.870 に答える
2

SQL Serverは、述語プッシュ(別名述語プッシュダウン)を使用して、クエリ条件を可能な限りソーステーブルに向かって移動します。それはあなたがそれらを括弧でくくった順序で物事を惜しみなく行うことはありません。オプティマイザーは、複雑なルール(本質的には一種のジオメトリ)を使用してクエリの意味を決定し、同じ最終データセットを返しながら最高のパフォーマンスを得るには、データへのアクセスを自由に再構築します。クエリロジックが要求すること。

クエリがますます複雑になるとオプティマイザがすべての可能な実行プランを徹底的に検索できず、最適ではないものになってしまう可能性があります。ただし、提示したような単純なケースは常に「見通され」、最適化されるとほぼ想定できます。

したがって、答えは、2つのクエリを組み合わせた場合と同じように優れたパフォーマンスが得られるはずです。ここで、結合している値が複合である場合、つまり、それらが計算または連結の結果である場合、サーバーが機能するため、インデックスを有用にする必要のある述語プッシュを取得することはほぼ確実ではありません。 tまたは、部分的な文字列に基づいて、または逆算術などを実行した後にシークを実行できません。

将来、ここでこのような質問をする前に、実行プランを自分で調べて、インデックスを使用していることを検証することをお勧めしますか?あなたは少しの実験であなた自身の質問に答えることができたでしょう。それでも質問がある場合は、投稿してください。それまでの間、あなたを助けてくれている人々への敬意の印として、あなた自身の調査を行ってみてください。

実行プランを表示するには、SQL Server Management Studio(2005以降)またはSQLクエリアナライザー(SQL 2000)で、メニューバーの[実行プランの表示]ボタンをクリックしてクエリを実行し、次のタブに切り替えることができます。実行計画のグラフィカルバージョンを表示する下部。マウスをさまざまな部分に少し突っ込んでカーソルを合わせると、どのインデックスがどのテーブルで使用されているかがすぐにわかります。

ただし、期待どおりでない場合は、サーバーが間違いを犯していると自動的に考えないでください。インデックスを使用せずにメインテーブルをスキャンすると、コストが低くなると判断される場合があります。ほとんどの場合、これは正しいことです。スキャンのコストが低くなる理由はたくさんあります。その1つは非常に小さなテーブルであり、もう1つは、サーバーが統計的に返す必要があると推測する行数がテーブルのかなりの部分を超えていることです。

于 2012-07-13T05:30:05.330 に答える
0

これらの両方のクエリは同じです。2番目のクエリは、変換中に最初のクエリとまったく同じように変換されます。

ただし、特定の要件がある場合は、コード全体を配置することをお勧めします。そうすれば、質問に答えるのがはるかに簡単になります。

于 2012-07-14T11:39:01.320 に答える