none
複数テーブル結合方法のパフォーマンスについて

    Question

  • お世話になります。

    SQLの基本なのかもしれませんがご教授ください。

    SELECT文で複数のテーブルを内部結合する場合、JOINと使うかどうかでパフォーマンスは変わるのでしょうか?

    また、条件を書く順番等も影響するのでしょうか?

    JOIN無し例>select * from TableA a, TableB b where a.ID = b.ID

    JOIN有り例>select * from TableA a inner join TableB b on a.ID = b.ID

     

    Wednesday, January 11, 2012 8:47 AM

All replies

  • 上記の例で、TableA と TableB は共に ID 列単独で プライマリキーになっているのであれば、

    恐らくコストは同じだと思います。

     

    ですが、

    >SELECT文で複数のテーブルを内部結合する場合、JOINと使うかどうかでパフォーマンスは変わるのでしょうか?

    >また、条件を書く順番等も影響するのでしょうか?

    という質問に答えようとすると、条件が少な過ぎます。

     

    インデックス等の状況で変わってくる話ですので、一概にどうとは言えません。

    ※SELECT文で複数のテーブルを内部結合する場合、JOINと使うかどうかでパフォーマンスは変わるのでしょうか?は恐らく Yes ですが・・・

     

    SQL Server クエリ オプティマイザ がクエリを解析したインデックス等が違えば勿論違います。

    実際の環境に Managment Studio で接続し、クエリ実行画面で「推定実行プランの表示」をして比較して下さい。

    Wednesday, January 11, 2012 10:16 AM
  • こちらが参考になると思います。

    [SQL初級] - SQLer 生島勘富 の日記


    Blog:プログラマーな日々 http://d.hatena.ne.jp/JHashimoto/
    Wednesday, January 11, 2012 10:45 AM
  • aviator_さんのおっしゃるとおり
    この場合はコスト的には同じで、インデックス等の状況で変わってくる話ですので、一概にどうとは言えないと思います。

    が、覚えておいていただきたいのは

    TableA
    ID,Name,Born
    1,Michael,1
    2,John,2
    3,Jenny,2
    4,Mike,3

    TableB
    ID,Name
    1,NewYork
    2,Washington
    3,California

    のような一般的なテーブルを結合してクライアントに返す場合
    JOINありの場合は
    TableA.ID,TableA.Name,TableB.ID,TableB.Born
    1,Michael,1,NewYork
    2,John,2,Washington
    3,Jenny,2,Washington
    4,Mike,3,California

    という結果をクライアントに返すことになります。
    Washingtonという文字が2回入っていますね。

    これを何十個というテーブルを結合して結果を返すとなると
    同じ文字列がずら~っと並ぶようなことになります。
    (よくあるのが都道府県名とか”男性”とか)

    これを通信するわけですから、通信環境が悪い場合は、なかなか結果が返ってこないケースがあり、
    あえてJoinせずに個別にテーブルをとってきたほうが、通信量が少なくなり応答が速いというケースがあります。
    が、これも一概には言えませんので、こういうケースがあることも覚えておいてもらえればと思います。

    Wednesday, January 11, 2012 10:48 AM
  • aviator_さん、 J.Hashimotoさん、サヴロウさん
    ご回答ありがとうございます。

    J.Hashimotoさんに教えていただいたサイトは参考になりました。あまりこのようなことを気にせずSQL組んでいました…

    情報が少なく申し訳ありません。
    もう少し詳しく書いてみます。

    テーブル:TableS
    列:ID_S(PK), ID_D

    テーブル:TableF
    列:ID_F(PK), ID_S, ID_I, FLAG_F

    テーブル:TableM
    列:ID_D(PK), ID_I(PK), NUM_M(PK)

    JOIN有>select m.ID_D, sum(m.NUM_M), count_big(*) as cnt from TableS s
                           inner join TableF f on s.ID_S = f.ID_S
                           inner join TableM m on f.ID_I = m.ID_I and f.ID_S = m.ID_S
                                   where f.FLAG_F = 1
                                       group by m.ID_D

    JOIN無>select m.ID_D, sum(m.NUM_M), count_big(*) as cnt from TableS s, TableF f, TableM m
                            where s.ID_S = f.ID_S and f.ID_I = m.ID_I and s.ID_S = f.ID_S and f.FLAG_F = 1
                                        group by m.ID_D

    このクエリをインデックス付きビューで作成した場合、TableSをupdateすると、JOIN無ビューがある方がJOIN有がある時と比べてupdateに時間が掛かります。
    ビューのインデックスはID_Dです。
    クエリを単独で実行するとどちらも時間に大差はありませんでした。確認時にはキャッシュをクリアしています。

    質問にだいぶ肉付けしてしまいましたが、よろしくお願いいたします。
    Wednesday, January 11, 2012 12:58 PM