必要なのは、特定のキーを持つレコードのすべてのフィールドの値を設定し(キーは実際にはコンポジットです)、そのようなキーを持つレコードがまだない場合にレコードを挿入することです。
REPLACE
は仕事をすることを意図しているようですが、同時にそのマニュアルページは INSERT ... ON DUPLICATE KEY UPDATE
を示唆しています。
どれを選択すればよいのか、その理由は何ですか?
私の頭に浮かぶREPLACE
の唯一の「副作用」は、INSERT ... ON DUPLICATE KEY UPDATE
がおそらくしないだろうが、自動インクリメント値をインクリメントすることです(残念ながら、私は使用しません)。他に考慮すべき実用的な違いは何ですか? REPLACE
がINSERT ... ON DUPLICATE KEY UPDATE
よりも優先される場合や、その逆の場合はどのような場合ですか?
REPLACE
は、内部的に削除を実行してから挿入を実行します。その行を指す外部キー制約がある場合、これは問題を引き起こす可能性があります。この状況では、REPLACE
が失敗するか悪化する可能性があります。外部キーがカスケード削除に設定されている場合、REPLACE
は他のテーブルの行を削除します。これは、REPLACE
操作の前後の両方で制約が満たされた場合でも発生する可能性があります。
INSERT ... ON DUPLICATE KEY UPDATE
を使用すると、この問題を回避できるため、推奨されます。
パフォーマンスの観点から質問に答えるために、両方の方法を使用してテストを行いました
次への置換:
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行
INSERT ... ON DUPLICATE KEY UPDATE
の代わりにREPLACE
を使用する場合、特定のキーに対して複数のクエリがすばやく到着すると、キーロックまたはデッドロックの問題が発生することがあります。 (カスケード削除を引き起こさないことに加えて)後者の原子性は、それを使用するより多くの理由です。
どの特定の場合、INSERT ... ON DUPLICATE KEY UPDATEよりもREPLACEを優先できますか?
FEDERATEDストレージエンジンINSERT...ON DUPLICATE KEY UPDATE
ステートメントを含むテーブルの場合、受け入れられるが、失敗する(エラー1022:書き込みできません;テーブル内のキーを複製する...)という難しい方法を見つけました。重複キー違反が発生した場合-MySQLリファレンスマニュアルの このページ の対応する箇条書きを参照してください。
幸いなことに、挿入後トリガー内でINSERT...ON DUPLICATE KEY UPDATE
の代わりにREPLACE
を使用して、変更をFEDERATEDテーブルに複製するという望ましい結果を達成することができました。
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 /
「重複キーエラーの場合、ストレージエンジンは削除と挿入ではなく更新としてREPLACEを実行する可能性がありますが、セマンティクスは同じです。」
すべての列をリストしない場合、REPLACE
は、言及されていない列を、置換された行のデフォルト値でリセットすると思います。 ON DUPLICATE KEY UPDATE
は、言及されていない列を変更しないままにします。