こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

INNER JOIN > EXISTS > IN

SQL Server 2008での話です。
製品テーブルと、その製品の売れ行きのランキングデータを格納するテーブルがあって、
売れ行きの良いものTOP10だけ取り出したいと思っています。
製品IDがキーになっています。

ランクテーブルから10位以内の製品IDをSELECTし、それをIN句に
入れるということをやっていたのですが、遅かったので、EXISTSに
書き変えました。
更に、INNER JOINにしてしまえば、WHERE句より実行されるので、
より速くなると聞き、試しているところです。
実際、速くはなったのですが、以下パターンだとそれほど差が出ません。
(データの件数のせいだとは思いますが…)
どちらがベターなのでしょうか。
Bのほうが先に絞り込みをしてから結合されるから、速い…ような気が
しているのですが、動き的には一緒だったりしますかね…。
もしより良い書き方がありましたらご教授ください。

■Aパターン
SELECT * FROM 製品テーブル
INNER JOIN ランクテーブル
ON 製品テーブル.製品ID = ランクテーブル.製品ID
AND ランクテーブル.順位 <= 10

■Bパターン
SELECT * FROM 製品テーブル
INNER JOIN
(
SELECT ランクテーブル.製品ID FROM ランクテーブル
WHERE
ランクテーブル.順位 <= 10
) TMP
ON TMP.製品ID = 製品テーブル.製品ID

投稿日時 - 2014-08-15 11:09:49

QNo.8717557

困ってます

このQ&Aは役に立ちましたか?

11人が「このQ&Aが役に立った」と投票しています

回答(2)

ANo.2

> 動き的には一緒だったりしますかね…。

実行プランを見れば分かります。
http://technet.microsoft.com/ja-jp/library/ms178071(v=sql.105).aspx

SQLServerのオプティマイザは賢いので、SQLクエリを多少変えた程度では変わらないはずです。
パフォーマンス向上にはインデックスの追加が有効かもしれない。

ランクテーブルにインデックス{順位, 製品ID}を追加

投稿日時 - 2014-08-18 10:27:34

ANo.1

どっちも、製品テーブルとランクテーブルを結合してから、順位が10以下を絞り込むので、速度はそんなに変わらないでしょう。

AもBも、製品テーブル全件とランクテーブル全件を結合してから、順位が10以下の物だけ抽出しているのは変わらないですから。

やるなら、順位が1~10の10個しか出てこない、順位テーブルのサブクエリを作って、そのサブクエリと製品テーブルを結合するのが良いでしょう。

クエリの高速化のコツは「絞込みして件数を減らしてから結合」です。

投稿日時 - 2014-08-15 11:50:52

あなたにオススメの質問