kagamihogeの日記

kagamihogeの日記です。

Oracleのdbms_random.valueで1とmaxの間によるランダムセレクションのばらつきを調べる

OracleのSAMPLE句によるランダムセレクションのばらつきを調べる - kagamihogeのblog の続き。SQLアンチパターンのランダムセレクションのベーシックな方法のオススメとして下記のやり方が紹介されている。

1から主キーの最大値までの間の値をランダムに選択することです。

SQLアンチパターン 15.5.1 1と最大値の間のランダムなキー値を選択する p.168 より抜粋

Oracleの場合、乱数生成の最小値・最大値を指定可能なDBMS_RANDOMパッケージのVALUEファンクションが使える。この関数使ったとき、ぱらけ具合がどんなもんかを調べる。

準備

OracleのSAMPLE句によるランダムセレクションのばらつきを調べる - kagamihogeのblogと同じテーブル構造、データ行数(3万件)、計測用のプログラムを用いる。計測の方法も同一。

ランダムセレクションは下記のクエリを実行する。dbms_random.valueで、主キー範囲の1〜最大値の乱数を出し、それを主キー検索条件の値にする。

select 
  hoge_id,
  hoge_value
from 
  hoge
where 
  hoge_id = floor(
    dbms_random.value(1, (select max(hoge_id) from hoge)+1)
  );

上記クエリの実行計画はこんな感じ。

結果

100万回時点でのグラフ。

1000万回後のグラフ。

感想とか

当然のことながらおよそランダムっぽい動作を確認できた。
実行速度は調べなかったのだけど、実行計画の通りインデックス使えるのでそんなに気にしなくても良さそうな気がしないでもない。
あとは、主キー値に歯抜けがあるとこのエントリで書いたような素朴なやり方は通じないけど、工夫の仕方はSQLアンチパターンに書いてあるので、そこはそれぞれの環境で創意工夫ってところでしょうかね。

参考文献&URL

SQLアンチパターン

SQLアンチパターン