本番環境の特定の基準を満たす複数の行(> 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がレプリケーションを行ベースに更新しました
更新はコンポジットINDEX(column_19, updatedOn)
の恩恵を受けます。
単一のSQLステートメントで実行できることを実行するためにクライアントループを使用することはほとんど決して速くはありません。
100万行以上の更新について話しているので、他にも議論する必要があります...
バッチでテーブルの数行以上を更新する必要はめったにありません。おそらくcolumn_20
はそのテーブルに属していません。これを回避するために、おそらく1行の小さなテーブルに属しているのでしょうか。多分何か。列のセマンティクスを説明する場合は、より具体的なアドバイスを提供できます。
大幅な更新に「時間がかかりすぎる」ように見える理由は、ROLLBACK
が必要になった場合に備えて保存するためです。
しかし、大量のUPDATE
またはDELETE
を実行する必要がある場合は、 チャンクで実行することをお勧めします 。そのドキュメントには、レプリケーションへの影響に関する注記があります。
より効果的な方法は、これをチャンクで行うことです。「大きなクエリは、小さなクエリよりも高速です」。
クエリの説明プラン(実行プラン)を確認し、必要に応じてインデックスを作成します。チャンクで実行するには、実際のクエリでLIMITを使用できます
同様の質問については私の回答を参照してください、それはレプリケーションシナリオもカバーしていますMySQLマスターおよびスレーブからの巨大なInnoDBテーブルからのデータの削除