はじめに
最近、ランダム抽選系の機能(いわゆる「恋愛おみくじ」)を実装する機会がありました。
最初はシンプルに「DBからランダムで1件取得」するだけだったのですが、
アクセスが増えるにつれてパフォーマンス問題が顕著になりました。
特に以下のような課題が発生しました:
- アクセス集中時のDB負荷増大
- ORDER BY RAND() の致命的な遅さ
- 同時アクセス時のレスポンス低下
- https://www.ichizenn.com/koi-mikuji/
今回は、その改善方法をまとめます。
問題点:ORDER BY RAND() は使うな
よくある実装:
SELECT * FROM omikuji ORDER BY RAND() LIMIT 1;
$min = 1;
$max = 10000;
$id = rand($min, $max);
SELECT * FROM omikuji WHERE id >= $id LIMIT 1;
メリット
超高速
インデックス効く
デメリット
欠番があると偏る
解決策②:IDキャッシュ(おすすめ)
さらに改善:
事前にIDリストをキャッシュ
そこからランダム抽選
$ids = file_get_contents('ids_cache.php');
$idList = explode(',', $ids);
$randomId = $idList[array_rand($idList)];
解決策