都内で働くSEの技術的なひとりごと

都内でサラリーマンやってます。マイクロソフト系(たまに、OSS系などマイクロソフト以外の技術も...)の技術的なことについて書いています。日々の仕事の中で、気になったことを技術要素関係なく気まぐれに選んでいるので記事内容は開発言語、インフラ等ばらばらです。なお、当ブログで発信、発言は私個人のものであり、所属する組織、企業、団体等とは何のかかわりもございません。ブログの内容もきちんと検証して使用してください。よろしくお願いします♪

MERGE JOIN だからといって、油断せずに MANY-TO-MANY ( 多対多 ) とか出てないか、実行プランをちゃんとチェックしてみる

 過去に MERGE JOIN の説明など、結合方式について説明しています。ryuchan.hatenablog.com

ryuchan.hatenablog.com

 MERGE JOIN は高速!っと思ったら、大間違いです。きちんと実行プランの細部までチェックしましょう。サンプルの実行プランは下記の通りです。MERGE JOIN のオペレータのその先に、SORT オペレータがあります。その一つに警告が出ています。
f:id:koogucc11:20150605192135p:plain
 
 あら、tempdb への書き込みが発生しています。さらに結構大量なレコードが!!
f:id:koogucc11:20150605192455p:plain

 なぜ、こんなことが発生するんでしょうか?犯人は下図の通りです。MERGE JOIN のオペレータを参照してみましょう。多対多( MANY-TO-MANY )が原因です。一対多 ( ONE-TO-MANY ) であれば問題ありません。
f:id:koogucc11:20150605192814p:plain

 MANY-TO-MANY の場合、結合したテーブルを一時的に TempDB に格納します。これがレスポンス悪化の原因です。MANY-TO-MANY の詳細は、Craig Freedman のブログを参照しましょう。(はい、他力)

 これを解消するには、いくつかのパターンはありますが、私は安易に INNER JOIN を INNER LOOP JOIN で Nested Loop に強制することにより解決しています。(一例ではありますが....)あくまでも、一例なのでご参考程度に....

※やっぱり、これおすすめ。

Microsoft SQL Server 2012 Internals (Developer Reference)

Microsoft SQL Server 2012 Internals (Developer Reference)