web-dev-qa-db-ja.com

一括更新と行単位の更新

本番環境の特定の基準を満たす複数の行(> 100k)を更新する必要があります。このクエリは時間がかかるため、遅いクエリになります。誰かが、一括更新を行う代わりに、更新クエリを行ごとに送信する必要があると私に言った。

例-古いクエリ:

update table_1 
set column_20 = 'abc' 
where updatedOn > date_sub(now(), interval 1day) and column_19 = 'xyz' 

新しいクエリ/メソッド:

select auto_increment_id_column  
from table_1 
where updatedOn > date_sub(now(), interval 1day) and column_19 = 'xyz' 

"for loop"上から抽出されたすべてのIDに対して、次に各IDに対してクエリを送信します。

update table_1 
set column_20 = 'abc' 
where auto_increment_id_column = id_from_for_loop;

この方法は直感に反しているようですので、実行する必要があるかどうかを確認してください。また、マスタースレーブのレプリケーションにどのように影響するか。

dbinfo-mysqlおよびステートメントベースのレプリケーションの使用

主な更新:最近、DBAがレプリケーションを行ベースに更新しました

2
vaibhav gupta

更新はコンポジットINDEX(column_19, updatedOn)の恩恵を受けます。

単一のSQLステートメントで実行できることを実行するためにクライアントループを使用することはほとんど決して速くはありません。

100万行以上の更新について話しているので、他にも議論する必要があります...

バッチでテーブルの数行以上を更新する必要はめったにありません。おそらくcolumn_20はそのテーブルに属していません。これを回避するために、おそらく1行の小さなテーブルに属しているのでしょうか。多分何か。列のセマンティクスを説明する場合は、より具体的なアドバイスを提供できます。

大幅な更新に「時間がかかりすぎる」ように見える理由は、ROLLBACKが必要になった場合に備えて保存するためです。

しかし、大量のUPDATEまたはDELETEを実行する必要がある場合は、 チャンクで実行することをお勧めします 。そのドキュメントには、レプリケーションへの影響に関する注記があります。

1
Rick James

より効果的な方法は、これをチャンクで行うことです。「大きなクエリは、小さなクエリよりも高速です」

クエリの説明プラン(実行プラン)を確認し、必要に応じてインデックスを作成します。チャンクで実行するには、実際のクエリでLIMITを使用できます

同様の質問については私の回答を参照してください、それはレプリケーションシナリオもカバーしていますMySQLマスターおよびスレーブからの巨大なInnoDBテーブルからのデータの削除

0
Abdul Manaf