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に変換されるのか、ログを見て意識していこうと思います!