回答編集履歴

1 微修正

tomari_perform

tomari_perform score 653

2017/07/25 18:54  投稿

> その1
⇒RAND()で時間がかかっているのは、
creation_time < '2016/10/29 00:00'
でヒットする件数分(10万件分くらい?)の
RAND()を発生させて、ソートしているため、
CPUも非常に時間がかかります。
> その2
⇒その1の時間で抽出した10件に対して、
tbl.id = tmp_tbl.id;
で抽出しています。
実際の動作は、
tbl.id = Xの結果を
UNION ALLで10回繰り返しているので、
SQLの解析時間もあり、その1より使い物にならない状態になっています。
> その3
⇒SQLが省略されているので、省略
> その4
⇒RAND()の発生回数を減らす対策の考え方として良いと思います。
もう一息!という感じですね。
他のSQLの結果から察すると、
accounts.id = tmp_tbl.id
にも時間(主にSQL解析時間と予想)がかかってそうです。
> どうすれば結果取得までの時間を短縮し、CPU使用率を低くできるか
> 悪くても0.5秒ぐらいで取得したい
⇒以下のような考え方でCPU使用率を低く、0.5秒くらいで取得できると思います。
案1)抽出条件にヒットする20~100件を(ORDER BY creation_time 等のINDEXに存在する項目で)先に取得し、
  その結果に対してRAND()を発生させて、10件取得する。
  ⇒INDEX破損がなければ、予想としては0.3秒程度です。
案2)案1において、update_time項目を追加し、その項目をソート項目とする。
  (毎回同じ100件の中からランダムに選ぶのを防げる)
  (毎回同じ100件の中からランダムに選ぶのを防げる)

思考するエンジニアのためのQ&Aサイト「teratail」について詳しく知る