Каковы практические различия между `REPLACE` и` INSERT ... ON DUPLICATE KEY UPDATE` в MySQL? - PullRequest
63 голосов
/ 07 февраля 2012

Мне нужно установить значения всех полей записи с определенным ключом (на самом деле ключ является составным), вставляя запись, если еще нет записи с таким ключом.

REPLACE кажется предназначенным для выполнения этой работы, но в то же время на его странице руководства предлагается INSERT ... ON DUPLICATE KEY UPDATE.

Какую из них мне лучше выбрать ипочему?

Единственный "побочный эффект" REPLACE, который мне приходит в голову, заключается в том, что он будет увеличивать значения автоинкремента (к счастью, я их не использую), тогда как INSERT ... ON DUPLICATE KEY UPDATE, вероятно, не будет.Какие еще практические различия следует учитывать?В каких конкретных случаях REPLACE может быть предпочтительнее, чем INSERT ... ON DUPLICATE KEY UPDATE и наоборот?

Ответы [ 7 ]

98 голосов
/ 07 февраля 2012

REPLACE внутренне выполняет удаление, а затем вставку.Это может вызвать проблемы, если у вас есть ограничение внешнего ключа, указывающее на эту строку.В этой ситуации REPLACE может дать сбой или хуже: если ваш внешний ключ установлен каскадным удалением, REPLACE приведет к удалению строк из других таблиц.Это может произойти, даже если ограничение было выполнено как до, так и после операции REPLACE.

Использование INSERT ... ON DUPLICATE KEY UPDATE позволяет избежать этой проблемы и поэтому является предпочтительным.

39 голосов
/ 15 января 2015

Чтобы ответить на вопрос с точки зрения производительности, я сделал тест, используя оба метода

Заменить на включает:
1.Попробуй вставить на стол
2. Если ошибка 1, удалите строку и вставьте новую строку

Вставка при обновлении дубликата ключа включает в себя:
1. Попробуйте вставить на стол
2. Если 1 не удается, обновите строку

Если все выполняемые шаги являются вставками, не должно быть никакой разницы в производительности. Скорость должна зависеть от количества обновлений. В худшем случае, когда все утверждения являются обновлениями

Я пробовал оба утверждения в моей таблице InnoDB, включающие 62 510 записей (только обновления). На скорости кемпинга:
Заменить на: 77,411 секунд
Вставка при обновлении дубликата ключа: 2,446 секунд

Insert on Duplicate Key update is almost 32 times faster.

Размер таблицы: 1 249 250 строк с 12 столбцами на Amazon m3.medium

8 голосов
/ 27 февраля 2013

При использовании REPLACE вместо INSERT ... ON DUPLICATE KEY UPDATE я иногда наблюдаю проблемы с блокировкой или тупиковой блокировкой, когда несколько запросов быстро приходят для данного ключа.Атомность последнего (помимо того, что он не вызывает каскадного удаления) является еще одной причиной для его использования.

3 голосов
/ 28 мая 2013

В каких конкретных случаях REPLACE может быть предпочтительнее, чем INSERT ... ON DUPLICATE KEY UPDATE и наоборот?

Я только что нашел трудный путь, который в случаетаблицы с механизмом хранения FEDERATED INSERT...ON DUPLICATE KEY UPDATE операторы принимаются, но не выполняются (с ошибкой 1022: невозможно записать; дубликат ключа в таблице ...), если происходит нарушение дубликата ключа - см. соответствующий пункт в эта страница Справочного руководства по MySQL.

К счастью, я смог использовать REPLACE вместо INSERT...ON DUPLICATE KEY UPDATE в моем триггере после вставки для достижения желаемого результата репликации изменений в таблицу FEDERATED.

2 голосов
/ 07 февраля 2012

Заменить кажется, что он делает две операции в случае, если ключ уже существует.Возможно, это означает, что существует разница в скорости между этими двумя значениями?

(ВСТАВИТЬ) одно обновление против одного удаления + одна вставка (ЗАМЕНА)

РЕДАКТИРОВАТЬ: мое предположение, что замена может быть медленнее, фактически полностьюнеправильно.Ну, в любом случае, согласно этому сообщению в блоге ... http://www.tokutek.com/2010/07/why-insert-on-duplicate-key-update-may-be-slow-by-incurring-disk-seeks/

1 голос
/ 15 апреля 2016

"Возможно, что в случае ошибки с дублированным ключом механизм хранения может выполнить ЗАМЕНУ как обновление, а не как удаление плюс вставка, но семантика та же."

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

1 голос
/ 24 октября 2013

Если вы не перечислите все столбцы, я думаю, REPLACE сбросит все безымянные столбцы со значениями по умолчанию в замененных строках.ON DUPLICATE KEY UPDATE оставит неизменными столбцы без изменений.

...