SQL発行されまくるスクリプト
あるデータを取得する必要があり、コンソールでスクリプトを実行しておりました。
すると、AWS RDSのProcessor load が90%を超えているというアラートが何度も鳴ってしまいましたw
OPさんにも心配をさせてしまいたした。
その時のスクリプトが以下です。
idsに調べたいhogeidを代入し、Hogeモデルのレコードと関連するmessageのレコード情報を引っ張っておりました。
messages = []
ids.each do |id|
message = Hoge.find_by(hogeid: id)&.message
messages << "#{message.id}........略"
end
puts messages
これだとレコード1つずつに対してSQLが発行されてしまっており、RDBへの負荷がとても大きくなってしまっていたようです。
さらに期間指定もしていない為、レコード全件見にいってしまっていたようです。。。
修正後のスクリプトが以下です。
いっぺんに100件ずつ処理を行うようにしてあげ、
includesで関連先レコード取得する際SQL発行されないようにし、
期間指定をして全件見にいかないようにしてあげました。
messages = []
ids.each_slice(100) do |new_ids|
pre_messages = Hoge.includes(:message).where(created_at: (DateTime.new(2019,6,6,7,00))..(DateTime.new(2019,6,6,21,00))).where(hogeid: new_ids)
pre_messages.each do |pre_message|
message = pre_message&.message
messages << "#{message.id}........略"
end
end
puts messages
これが正しいやり方なのかは分かりませんが、発行されるSQLがめちゃくちゃ減りました。
データの取得できるスピードも格段にアップしました。
最初のスクリプトだと一度に数百件ずつidsを代入していてもアラートが鳴っていたのが、1万件以上のidを代入してもアラートもならなくなりました。
アクティブレコードのメソッドがどんなSQLに変換されるのか、ログを見て意識していこうと思います!