BKA JOINについて

    MySQL Casual Talks @gumi福岡
                     2012/06/27
自己紹介

名前: 松崎 学

所属: 株式会社キャム (SaaS型の経営管理システムを提供中)
       http://www.cam-net.co.jp/
Twitter: matsumana

最近のお仕事:Javaプログラマ(Rubyもほんの少し)、 インフラ

最近の興味: Scala, Ruby, Python, Play, Node.js, AWS,
             Hadoop, Asakusa Framework, MongoDB, Fluentd, Vyatta
データベースと私
Oracle歴
14年 (7.1∼ on Windows , Solaris, Linux)

PostgreSQL歴
1.5年 (9.0∼ on Linux)

MySQL歴
1ヶ月程 (今回のLTをきっかけに勉強を始めました)
初学者ですが、
よろしくお願いします m(_ _)m




http://www.flickr.com/photos/dapperscoo/166797625/
JOINアルゴリズムあれこれ
                   SQL実行計画に出てくるアレです

                   片方のテーブルを外部表(駆動表)とし、
                   もう片方のテーブルをループで回してJOINする。
Nested Loop JOIN
                   (要するに2重ループ)
                   外側のループ=外部表   内側のループ=内部表


                   まず、両方のテーブルをJOIN項目でソートして、
Merge JOIN
                   先頭から順次読み込んでJOINする。




                   まず、JOIN項目でHashテーブルを作成し、
Hash JOIN
                   そのHashテーブルを元にJOINする。
MySQLにはNested Loop Join
しかない。
※だから遅いという事では決してありません。

クエリ次第だと思います。
しかし、

 Block Nested Loop Join
 が実装されているので、

特定の条件を満たせば、
内部表のループ回数が大幅に
      減少する。
MySQL 5.1 リファレンスマニュアル 抜粋

   http://dev.mysql.com/doc/refman/5.1-olh/ja/nested-
   loop-joins.html

   ブロック入れ子ループ join アルゴリズム

ブロック入れ子ループ (BNL、Block Nested-Loop) join アルゴリズム
は、外側のループで読み取った行のバッファリングを使用して、内側
のループで必要となるテーブルの読み取り回数を減らします。たとえ
ば、バッファーに 10 行を読み込み、このバッファーを次の内側ルー
プに渡すと、内側ループで読み取る各行をバッファー内の 10 行すべ
てと比較できます。これにより、内側のテーブルを読み取る必要のあ
る回数が大幅に減少します。
新しいJOINアルゴリズム登場!

 Batched Key Access JOIN (BKA JOIN)
 5.6.3 m6から利用可能。


 5.6は2011/04にリリースされた、
 まだDevelopment Releaseなバージョンです。


 ※今日時点の最新は 「5.6.5 m8」
BKA JOINとは?
http://nippondanji.blogspot.jp/2011/10/
mysqlmysql-563-m6.html

BKA JOINは変形NLJ(Nested Loop JOIN)とも言うべきもので、内部表からのレコー
ドのフェッチをひとつずつではなくまとめて行う。先に駆動表から結合するキーの
値をいくつかピックアップし、それを内部表に対してまとめて渡す。(Index
Condition Pushdownする。)すると、内部表ではMRR(Multi Range Read)最適化に
よってアクセスがソートされ、必要なレコードを最適な順序でフェッチすることに
なり、JOINが高速化するというわけだ。

InnoDBやMyISAMでは、MRRによる高速化が見込めるのははセカンダリインデックス
によるアクセス時だけである。(主キーでアクセスする場合には別段変わらな
い。)従って内部表のセカンダリインデックスを使って結合する場合には高速化が
見込めるだろう。BKAが使われているかどうかは、EXPLAINでExtraフィールドを見れ
ば分かる。
http://nippondanji.blogspot.jp/2011/04/mysql-56.html

   ICP (Index Condition Pushdown)
   これまでストレージエンジンからフェッチしたレコードをMySQLが
   評価してWHERE句の条件による絞り込みを行っていたが、インデッ
   クスが貼られたカラムを用いた評価については、ストレージエンジン
   へ条件式を渡し(プッシュダウンし)、ストレージエンジン側で評価
   を行わせることによってオーバーヘッドの低減をはかる。


   MRR (Multi Range Read)
   セカンダリインデックスの条件に合致するレコードを複数フェッチす
   る場合、レコードはセカンダリインデックスとは無関係に並んでいる
   ため、多くのランダムI/Oが発生する。先にセカンダリインデックス
   のキーだけを読み取って、主キーの順にソートしてからレコードを
   フェッチすることにより、ランダムディスクI/Oの低減を期待できる。
MySQL 5.6 Reference Manual


Batched Key Access Joins
http://dev.mysql.com/doc/refman/5.6/en/bka-
optimization.html

Index Condition Pushdown Optimization
http://dev.mysql.com/doc/refman/5.6/en/index-
condition-pushdown-optimization.html

Multi-Range Read Optimization
http://dev.mysql.com/doc/refman/5.6/en/mrr-
optimization.html
要約すると

BKA JOINは駆動表のJOINキーをバッファリングした
後、ストレージエンジンにまとめて送る。

内部表のフェッチはストレージエンジンで行われる。
ストレージエンジンとのやり取り回数が減るので、
オーバーヘッドが低減。

内部表はMRRにより最適な順番でフェッチされる
ため、ランダムアクセスI/Oが低減。
BNL JOINより
だいぶ早そうですね!!
BKA JONがICPとMRRの上に立脚しているイメージ

                                       BKA JOIN




                                         ICP
                                          +
                                         MRR




http://www.flickr.com/photos/robwithtwobs/310185817/
お薦め書籍
  本当はソースを理解して、内部までお話したかったのですが、
              力不足でした・・・><
興味のある方は sql/sql_select.cc あたりからぜひ読んでみてください。
NetBeansやEclipseを使えば
カジュアルにソースが読めます
まとめ
     MySQLは
  ドキュメント、書籍、
ブログエントリが充実していて、
 初学者でも取っ付きやすい
    カジュアルな
  データベースである。
Facebookのグループにも
     ぜひご参加ください

福岡インフラ勉強会

https://www.facebook.com/groups/100825430047874/
ご清聴ありがとう
ございました。

MySQL Casual Talks LT 20120627