LoginSignup
8
8

More than 1 year has passed since last update.

1000万レコードのバルクupdateが遅すぎ

Last updated at Posted at 2021-09-08

検証dbを作成する際のデータマスキングで、
1000万レコードに対して一括UPDATEを行うことがあったが、1時間ほどかかった。
以下の①,②を考える。

①なぜここまで遅くなるのか
②どうすれば早くなるのか

実行したSQL

update users 
set name = 'ダミー'

調査

以下の記事にUPDATE文を実行すると起きることがわかりやすくまとめられていた。

引用

RDBMSはSQL文1を受け取ると,SELECT文を受け取った時と同じように構文解析を行います。そして,UPDATE文であることを理解します。続いて,UPDATE対象のレコードを探します。このレコードを探す方法は,SELECT文と同じです。まず,「メモリー・バッファ」内に対象のレコードが存在していないかを確認し,存在していない場合は,ディスク上の「データベース・ファイル」から読み込みます。そして,メモリー・バッファ内に読み込んだ対象のレコードの値を指定された値に更新します。

つまり、updateの時
メモリにはupdate対象のレコードが展開され、さらにその更新後の値も保持する。


上記のようなことが、1000万レコードに対して実行された際簡単にメモリが溢れて、
スワップが起きてしまい遅くなってしまっていたよう。


①の原因を考えると、単純に一回にメモリに乗せる量を減らせばいいと推測できる。
以下の様に10回のupdateに分けた。
実行時間は、
一回あたり40秒 * 10 = 6分40秒
だいぶ早くなった。
ストアドプロシージャなどを使ってもう少し実行しやすい形にしたい。。

update users 
set name = 'ダミー'
where between 1 AND 1000000;
update users 
set name = 'ダミー'
where between 1000001 AND 2000000;
           
           
           
update users 
set name = 'ダミー'
where between 9000001 AND 10000000;
8
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
8