В MySQL это быстрее удалять, а затем вставить или быстрее обновлять существующие строки?
-
26-09-2019 - |
Вопрос
Прежде всего, позвольте мне просто сказать, что я использую PHP Framework Yii, поэтому я хотел бы остаться в своем определенном наборе SQL-оператора, если это возможно. Я знаю, что я мог бы создать одно огромное долгое заявление SQL, которое сделало бы все, но я бы предпочел не туда.
Хорошо, представьте, у меня есть пользователи стола и таблица фаворита. Тогда у меня есть форма, где пользователи могут выбрать их цветные настройки, проверив один или несколько флажков из большого списка возможных цветов.
Эти результаты хранятся в виде нескольких строк в таблице Favcolors, как это (ID, user_id, color_id).
Теперь представьте, что пользователь входит и меняет их цветные предпочтения. В этом сценарии какое было бы наиболее эффективным способом получения новых цветовых предпочтений в базу данных?
Опция 1:
- Сделайте массу удаления всех строк, где user_id совпадает
- Тогда сделайте массовую вставку всех новых строк
Вариант 2:
- Пройдите через каждую текущую строку, чтобы увидеть, что изменилось, и обновите соответственно
- Если нужно вставить больше строк, сделайте это.
- Если строки должны быть удалены, сделайте это.
Мне нравится вариант один, потому что он требует только двух утверждений, но что-то просто чувствует себя неправильно, чтобы удалить ряд, чтобы потенциально потенциально отложить практически то же самое данные. Также проблема создания идентификаторов автоматически увеличения на более высоких значениях, а также Я не знаю, следует ли избегать того, если это возможно.
Вариант 2 потребует намного больше программирования, но предотвратит ситуации, когда я бы удалил строку, просто чтобы снова создать его. Однако добавление большего количества нагрузки в PHP не стоит того, чтобы уменьшить нагрузку для MySQL.
Есть предположения? Что бы вы все сделали?
Решение
UPDATE
намного быстрее. Когда ты UPDATE
, Записи стола просто переписаны новыми данными. И все это должно быть сделано снова на INSERT
.
Когда ты DELETE
, Индексы должны быть обновлены (запомнить, вы удалите всю строку, а не только столбцы, необходимые для изменения), и блоки данных могут быть перемещены (если вы попали в PCTFREE
ограничение). Также удаление и добавление новых изменений записи идентификаторов на AUTO_INCREMENT, поэтому, если эти записи имеют отношения, которые будут сломаны, или потребуют бы обновления. Я бы пошел UPDATE
.
Вот почему вы должны предпочесть INSERT ... ON DUPLICATE KEY UPDATE
вместо REPLACE
.
Первый - это UPDATE
операция в случае нарушения ключей, в то время как последний DELETE / INSERT
ОБНОВИТЬ: Вот пример INSERT INTO table (a,b,c) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE c=c+1;
Для более подробной информации об обновлении чтения документация
Другие советы
Филипп, ты попробовал делать подготовленные заявления? С подготовленными утверждениями вы можете загрузить один запрос с разными параметрами и вызовите его несколько раз. В конце вашего цикла вы можете выполнить все их с минимальным количеством сетевой задержки. Я использовал подготовленные заявления с PHP, и он отлично работает. Мало более запутанно, чем у Java подготовленные заявления.