hidekatsu-izuno 日々の記録

プログラミング、経済政策など伊津野英克が興味あることについて適当に語ります(旧サイト:A.R.N [日記])

「メインメモリ上での13の等価結合手法の実験的比較」を読む

日本におけるデータベースの大家である kumagi さんが「An Experimental Comparison of Thirteen Relational Equi-Joins in Main Memory」という論文を紹介していた。

 

 

システム開発の実務においても、プロジェクト後半になると著しくパフォーマンスの悪いクエリが見つかりパフォーマンス・チューニングをせざるをえない状況が多く発生する。このような場合、ヒント句を使い結合方法を変更するというのは割と重要なテクニックのひとつであるため、大変興味をそそられる内容だ。*1

 

論文中では詳細な分析がなされているが、結論的なものが「LESSONS LEARNED(教訓)」という節にまとまっているので、その部分を抜粋しておく(ほとんど kumagi さんの要約で尽きてる感はありますが)。

 

  1. 小さい入力に対し CRP* アルゴリズムパーティションを使い並列で結合する手法群)を使うな
    • 800万件以下だとスレッド化やデータが複数のページに分かれるコストの方が大きくなる
  2. 実験に使う設定は明確にしろ(省略)
  3. 大規模な結合に際し、パーティション化すべきか迷うようならパーティション化しろ
    • パーティション化することでパフォーマンスが劣化することはほとんどない。
  4. 結合に使うページサイズは大きくしろ
  5. ソフトウェアベースの Write Combine Buffer を使え(省略)
  6. パーティションベースのためのアルゴリズムには適切なパーティションビット数を使え(省略)
  7. 可能な限りシンプルなアルゴリズムを使え
    • シンプルなアルゴリズムを使った方が、結果的に高速でメモリ消費も少ないとのこと
      (大量件数を処理するので、そういう結果になるのもわかる気がします)
  8. NUMA を意識しろ(省略)
  9. 結合時間がクエリの時間というわけではないので注意しろ
    • 結合時間は全体の10~15%しか占めない
      (一般論としてはそうだけど、これは場合によるのでは。索引なしの結合から索引のありの結合に変えれば大きく変わるし、Oracle Exadataだとネステッドループ結合をハッシュ結合に変えただけで劇的に高速化することもよくある)

*1:オーソドックスな改善手法としては結合項目にインデックスを張れだけど、それ以上にパフォーマンス改善が必要な場合には、クエリの改善、インデックスの固定、結合方法の変更、結合順序の固定、パーティション化などの方法を取るのが一般的な流れだと思う。