MySQL における Bulk Update
またハマったのでメモ。
begin; delete from t; insert into t select ...; commit;
とかやると、完了までの間、他の更新がブロックされてしまう。更新系と参照系が同一のウェブサーバで動いていたりすると、サービス全体がその間利用不可能になる、ということでもある。したがって
for ($id_start = 0; $id_start < $id_max; $id_start += BLOCK_SIZE) { $dbh->begin_work; $dbh->do( $dbh->printf( 'delete from t where %d<=id and id<%d', $id_start, $id_start + BLOCK_SIZE, ), ); $dbh->do( $dbh->printf( 'insert into t select ... where %d<=id and id<%d', $id_start, $id_start + BLOCK_SIZE, ), ); $dbh->commit; }
みたく分割すべき。