SQLアンチパターンを読み始めたので、1つ1つ書いてのメモです
目的
アンチパターン:データをランダムにソートする
アンチパターン
SELECT * FROM Bugs ORDER BY RAND() LIMIT 1;
- ソートは再現性もあり、インデックスのメリットも得られる
- インデックスとは、ある列の値を事前にソートしたもの
RAND関数を利用すると、インデックスのメリットが得られない
- データベースを手作業でソートしているのと同じ(データスキャン)
- データスキャンは、全体をスキャンしても利用するのは1行だったりするので無駄に終わることも多い
用いてもいいパターン
- 数が少なく、増えないデータ(都道府県とか)
解決策
- 1 と最大値の間のランダムなキー値を選択する
- 欠番がないことが前提
- 欠番の穴の後にあるキー値を選択する
- すべてのキー値のリストを受けとり、ランダムに 1 つを選択する
- アプリケーション側で対応する
- オフセットを用いてランダムに行を選択する
- データセットの行数をカウントし、0 と行数までの間 の乱数を返す技法
まとめ
クエリには最適化できないものもあります。最適化できない場合は、別のアプローチを採用しましょう。
感想
ランダムは、遅いのでアプリケーション側でやるようになった