0
   表T1表T2
   + ---- + ------------ + + ---- + ------------ +
   | Id | 名前| | Id | Some_Data |
   + ---- + ------------ + + ---- + ------------ +
   | | | | | |

クエリ1:

SELECT * FROM T1 JOIN T2 ON T1.Id=T2.Id WHERE T1.Id=1001

クエリ2:

SELECT * FROM T1 JOIN T2 ON T1.Id=T2.Id WHERE T2.Id=1001

T2に1,000万行があり、そのうち100行だけがId = 1001である場合、上記のクエリのどれを使用するのが適切ですか?または、SQL Serverは何を最善にすべきかを知るのに十分賢いので、それは問題ではありませんか?

ありがとう。

4

7 に答える 7

2

インデックスが両方のID列で使用可能な場合、ハッシュ結合のいくつかのバリアントが使用され、テーブルの順序は関係ありません。

インデックスが利用できない場合は、NL結合をより効率的にするために、左側のテーブルにwhere句を設定するのが理にかなっています(参加しているテーブルの統計に基づいて、MSSQLSERVERは順序を入れ替えるのが賢明だと思います。自体)

于 2012-08-22T05:11:50.780 に答える
1

どうですか:

SELECT * FROM T1 JOIN T2 ON (T1.Id=T2.Id AND T2.Id=1001)

彼らは、置くT2.Id=1001ことは行をフィルタリングしてから選択するだろうと言いますが、それを入れることWhere T2.Id=1001は最初に条件のためにすべての行を選択してT1.Id=T2.Idから適用しますT2.Id=1001

于 2012-08-22T05:05:51.303 に答える
1

私の場合、Query2の方が適切です。

SELECT * FROM T1 JOIN T2 ON T1.Id=T2.Id WHERE T2.Id=1001

返される行が制限されるため、より効率的になりますが、ドキュメントを確認することもできます。

于 2012-08-22T05:06:11.547 に答える
1

結果をすばやく取得するには、両方のid列に非クラスター化インデックスを設定し、上記のクエリのいずれかを使用する必要があると思います。そうでなければ、上記のクエリのいずれでもクエリをより速く処理できるとは思いません。そのような場合はインデックスが必要です。

于 2012-08-22T07:10:45.687 に答える
1

ここでの問題は、何百万もの行を含む結合が常に最初に来て、その後にのみwhere句が来ることだと思います。代わりにテーブルでこれを試して、メッセージタブでタイムスタンプを確認してください。

declare @t1 table (id int, name nvarchar(100));
declare @t2 table (id int, name nvarchar(100));

insert into @t1 (id, name) values (1, 'a')
insert into @t1 (id, name) values (2, 'b')
insert into @t1 (id, name) values (3, 'c')
insert into @t1 (id, name) values (4, 'd')
insert into @t1 (id, name) values (5, 'e')

insert into @t2 (id, name) values (5, 'e')
insert into @t2 (id, name) values (5, 'f')
insert into @t2 (id, name) values (5, 'g')
insert into @t2 (id, name) values (5, 'h')
insert into @t2 (id, name) values (5, 'i')
insert into @t2 (id, name) values (6, 'j')
insert into @t2 (id, name) values (7, 'k')
insert into @t2 (id, name) values (8, 'l')

print getdate()
-- this is your select statement
select * from @t1 t1 inner join @t2 t2 on t1.id = t2.id where t1.id = 5;
print getdate()
-- this is your select statement
select * from @t1 t1 inner join @t2 t2 on t1.id = t2.id where t2.id = 5;
print getdate()
-- this is done with a WITH to do the filtering beforehand
-- of course, indices will affect the performance a lot
with w2 (id, name) as (select * from @t2 where id = 5) 
select * from w2 inner join @t1 t1 on w2.id = t1.id
print getdate()

もちろん、私のサンプルデータを無視して、WITH句のようにテーブルを使用してください。

于 2012-08-22T07:36:23.330 に答える
1

最初にフィルタリングしてから参加するのはどうですか

SELECT * FROM T1 
JOIN (SELECT Id FROM T2 WHERE T2.Id=1001) T2
ON T1.Id=T2.Id 
于 2012-08-22T07:52:15.747 に答える
0

まず、これは私が直面している本当の質問であり、データベースは、いくつかのレポートを生成するための読み取り専用アクセス権を持っているサードパーティのソフトウェア製品からのものです。

すべての非常に役立つ回答者から、私は簡単な答えはないことを収集します。投稿から、最初にキー付きの列にインデックスが付けられていることを確認してから、SQLServerに最適化を任せてください。

ありがとうございます。

于 2012-08-22T13:41:54.377 に答える