• 締切済み

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

みんなの回答

  • todo36
  • ベストアンサー率58% (728/1234)
回答No.2

> 動き的には一緒だったりしますかね…。 実行プランを見れば分かります。 http://technet.microsoft.com/ja-jp/library/ms178071(v=sql.105).aspx SQLServerのオプティマイザは賢いので、SQLクエリを多少変えた程度では変わらないはずです。 パフォーマンス向上にはインデックスの追加が有効かもしれない。 ランクテーブルにインデックス{順位, 製品ID}を追加

回答No.1

どっちも、製品テーブルとランクテーブルを結合してから、順位が10以下を絞り込むので、速度はそんなに変わらないでしょう。 AもBも、製品テーブル全件とランクテーブル全件を結合してから、順位が10以下の物だけ抽出しているのは変わらないですから。 やるなら、順位が1~10の10個しか出てこない、順位テーブルのサブクエリを作って、そのサブクエリと製品テーブルを結合するのが良いでしょう。 クエリの高速化のコツは「絞込みして件数を減らしてから結合」です。

関連するQ&A