web-dev-qa-db-ja.com

MySQLの `REPLACE`と` INSERT ... ON DUPLICATE KEY UPDATE`の実際の違いは何ですか?

必要なのは、特定のキーを持つレコードのすべてのフィールドの値を設定し(キーは実際にはコンポジットです)、そのようなキーを持つレコードがまだない場合にレコードを挿入することです。

REPLACE は仕事をすることを意図しているようですが、同時にそのマニュアルページは INSERT ... ON DUPLICATE KEY UPDATE を示唆しています。

どれを選択すればよいのか、その理由は何ですか?

私の頭に浮かぶREPLACEの唯一の「副作用」は、INSERT ... ON DUPLICATE KEY UPDATEがおそらくしないだろうが、自動インクリメント値をインクリメントすることです(残念ながら、私は使用しません)。他に考慮すべき実用的な違いは何ですか? REPLACEINSERT ... ON DUPLICATE KEY UPDATEよりも優先される場合や、その逆の場合はどのような場合ですか?

63
Ivan

REPLACEは、内部的に削除を実行してから挿入を実行します。その行を指す外部キー制約がある場合、これは問題を引き起こす可能性があります。この状況では、REPLACEが失敗するか悪化する可能性があります。外部キーがカスケード削除に設定されている場合、REPLACEは他のテーブルの行を削除します。これは、REPLACE操作の前後の両方で制約が満たされた場合でも発生する可能性があります。

INSERT ... ON DUPLICATE KEY UPDATEを使用すると、この問題を回避できるため、推奨されます。

98
Mark Byers

パフォーマンスの観点から質問に答えるために、両方の方法を使用してテストを行いました

次への置換:
1。テーブルに挿入してみます
2。 1が失敗した場合、行を削除して新しい行を挿入します

重複キー更新での挿入には以下が含まれます
1。テーブルに挿入してみます
2。1つが失敗した場合、行を更新します

関連するすべてのステップが挿入である場合、パフォーマンスに違いはありません。速度は、関連する更新の数に依存する必要があります。最悪の場合は、すべてのステートメントが更新される場合です

62,510エントリ(更新のみ)を含むInnoDBテーブルで両方のステートメントを試しました。キャンピング速度について:
置換先:77.411秒
重複キーの更新時に挿入:2.446秒

Insert on Duplicate Key update is almost 32 times faster.

テーブルサイズ:Amazon m3.mediumの12列の1,249,250行

39
katrix

INSERT ... ON DUPLICATE KEY UPDATEの代わりにREPLACEを使用する場合、特定のキーに対して複数のクエリがすばやく到着すると、キーロックまたはデッドロックの問題が発生することがあります。 (カスケード削除を引き起こさないことに加えて)後者の原子性は、それを使用するより多くの理由です。

8
Andrew Mao

どの特定の場合、INSERT ... ON DUPLICATE KEY UPDATEよりもREPLACEを優先できますか?

FEDERATEDストレージエンジンINSERT...ON DUPLICATE KEY UPDATEステートメントを含むテーブルの場合、受け入れられるが、失敗する(エラー1022:書き込みできません;テーブル内のキーを複製する...)という難しい方法を見つけました。重複キー違反が発生した場合-MySQLリファレンスマニュアルの このページ の対応する箇条書きを参照してください。

幸いなことに、挿入後トリガー内でINSERT...ON DUPLICATE KEY UPDATEの代わりにREPLACEを使用して、変更をFEDERATEDテーブルに複製するという望ましい結果を達成することができました。

3
w5m

Replaceは、キーがすでに存在する場合に2つの操作を行うようです。おそらく、それは2つの間に速度の違いがあることを意味しますか?

(INSERT)1つの更新と1つの削除+ 1つの挿入(REPLACE)

編集:交換が遅いかもしれないという私の含意は、実際には完全に間違っています。とにかく、このブログの投稿によれば... http://www.tokutek.com/2010/07/why-insert-on-duplicate-key-update-may-be-slow-by-incurring -disk-seeks /

2
Isaac Fife

「重複キーエラーの場合、ストレージエンジンは削除と挿入ではなく更新としてREPLACEを実行する可能性がありますが、セマンティクスは同じです。」

http://dev.mysql.com/doc/refman/5.7/en/replace.html

1
user3522775

すべての列をリストしない場合、REPLACEは、言及されていない列を、置換された行のデフォルト値でリセットすると思います。 ON DUPLICATE KEY UPDATEは、言及されていない列を変更しないままにします。

1
Barmar