Подтвердить что ты не робот

Каковы практические различия между `REPLACE` и` INSERT... ON DUPLICATE KEY UPDATE` в MySQL?

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

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

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

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

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

Вставить в Duplicate Key Update включает: 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

Ответ 3

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

Ответ 4

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

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

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

Ответ 5

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

(INSERT) одно обновление по сравнению с одним удалением + одна вставка (ЗАМЕНИТЬ)

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

Ответ 6

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

Ответ 7

"Возможно, что в случае ошибки с дубликатными ключами механизм хранения может выполнять REPLACE как обновление, а не вставку delete plus, но семантика одинакова."

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