Progaku-copy / progaku-archive

Progakuのアーカイブ用のアプリ
0 stars 1 forks source link

ダミーデータの作成をバルクインサートで行えるようにする #60

Open kuri0616 opened 2 months ago

kuri0616 commented 2 months ago

背景

現在のseed.rbのダミーデータ作成処理は、単一のインサート処理で行うようになっている。 少量のデータ作成では、問題ないが大量のデータを作成する場合、レコードの追加の回数分、DBサーバとの通信やクエリの解析等の重い処理が行われるため、データベースへの負荷が高くなったり、処理に時間がかかりパフォーマンスが低下する。

ゴール

seedファイルを変更し、バルクインサートで1回のクエリでデータを追加できるようにする

参考

activerecord_import というgemを使用しても良さそうです。

kakeru-one commented 2 months ago

1件レコードを追加するたびにデータベースへの接続、切断を行うため、多数のコネクションが発生する

これはActiveRecordではコネクションプーリングされているので、少し違うと思います。 参考: https://cgs580.hatenablog.com/entry/2024/01/01/124633#:~:text=%E3%82%B3%E3%83%8D%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%97%E3%83%BC%E3%83%AB%E3%81%A8%E3%81%AF%E3%80%81Rails,%E3%81%AE%E3%82%B0%E3%83%AB%E3%83%BC%E3%83%97%E3%81%AE%E3%81%93%E3%81%A8%E3%81%A7%E3%81%99%E3%80%82


レコード追加の度にトランザクションが発生し、そのたびにコミットやロールバックが行われる。 上記によりデータベースへの負荷が高くなり、パフォーマンスが低下する。

実はこれはN回クエリが発行されることによる副作用の一つでしかないですね。 Slackでも言ったように、DBクライアントとDBサーバーとのネットワークI/Oであったり、 DBのパーサーがSQLをパースして、オプティマイザーがパースしたSQLをもとに実行計画を立てる、 と言ったことをN回行うことになります。 これによって、時間計算量が増加することが実行の遅さを招いています。 (バルクインサートだとO(1)で済むのに、O(N)になってしまっている。)

kuri0616 commented 2 months ago

これはActiveRecordではコネクションプーリングされているので、少し違うと思います。 そうだったのですね 設定ファイルに記載した数だけプールするから都度、接続、切断は行なっていないのですね!

実はこれはN回クエリが発行されることによる副作用の一つでしかないですね。 Slackでも言ったように、DBクライアントとDBサーバーとのネットワークI/Oであったり、 DBのパーサーがSQLをパースして、オプティマイザーがパースしたSQLをもとに実行計画を立てる、 と言ったことをN回行うことになります。 これによって、時間計算量が増加することが実行の遅さを招いています。 (バルクインサートだとO(1)で済むのに、O(N)になってしまっている。)

確かに、解析や実行計画を立てるのは重い処理になると以前読んだ本にも書いてあった気がします それに加えてデータの入出力もN回なのか1回なのかでは、大きな差になりそうですね・・ 教えていただきありがとうございます!