Множественные обновления MYSQL

#mysql #sql #performance

#mysql #sql #Производительность

Вопрос:

Я хочу обновить один и тот же столбец таблицы для разных случаев за один раз. Каков наилучший способ, которым я могу этого добиться? Например, я хочу добиться того же, что и приведенные ниже инструкции в одном SQL-запросе :

 UPDATE DANCER_TYPE SET TYPE = 'BALLET' WHERE LOGIN = 'arachel';
UPDATE DANCER_TYPE SET TYPE = 'EXOTIC_BELLY_DANCER' WHERE LOGIN = 'mandanah';
UPDATE DANCER_TYPE SET TYPE = 'JAZZ' WHERE LOGIN = 'kbianca';
UPDATE DANCER_TYPE SET TYPE = 'FUSION' WHERE LOGIN = 'lmorgan';
UPDATE DANCER_TYPE SET TYPE = 'BOLLYWOOD' WHERE LOGIN = 'idcruz';
UPDATE DANCER_TYPE SET TYPE = 'SAMBA' WHERE LOGIN = 'pcastillo';
  

Каков наилучший способ обновить столбец DANCER_TYPE, используя один запрос, наиболее масштабируемым и эффективным способом?

Комментарии:

1. Какую проблему вы пытаетесь решить? Сама причина, по которой вам нужно, чтобы это было только одно утверждение?

Ответ №1:

 UPDATE DANCER_TYPE
   SET TYPE = CASE LOGIN 
                      WHEN 'arachel' THEN 'BALLET' 
                      WHEN 'mandanah' THEN 'EXOTIX_BELLY_DANCER' 
                      ELSE 'YOURELSEVALUE'
                   END;
  

должно работать в вашем случае (только 2 примера)

Комментарии:

1. если вы не хотите ничего делать с else, просто используйте: ELSE NULL

2. Без WHERE это будет сканировать всю таблицу и изменять каждую строку!

3. @RickJames разве это не то, чего хочет OP: автоматически назначать тип для каждого танцора

Ответ №2:

Пример использования — ВЫРАЖЕНИЕ

 UPDATE DANCER_TYPE 
SET TYPE = CASE WHEN LOGIN = 'arachel' THEN 'BALLET'  
                WHEN LOGIN = 'mandanah' THEN 'EXOTIC_BELLY_DANCER' 
                WHEN LOGIN = 'kbianca' THEN 'JAZZ' 
                WHEN LOGIN = 'lmorgan' THEN 'FUSION'  
                WHEN LOGIN = 'idcruz' THEN 'BOLLYWOOD' 
                WHEN LOGIN = 'pcastillo' THEN 'SAMBA'            
            END
 WHERE LOGIN IN ('arachel', 'mandanah','kbianca','lmorgan','idcruz''pcastillo');
  

Комментарии:

1. В зависимости от данных, это может быть идея добавить where LOGIN IN ('arachel', ...) , чтобы уменьшить размер транзакции.

2. Да, s make sens -That поэтому уже разместите ДРУГУЮ часть, которая установит то же значение, если указанное выше условие не выполняется

3. Я не знаю, как Oracle обрабатывает значение столбца, обновленное до того же значения, что и раньше. Включено ли это в наборы записей и т.д.?

Ответ №3:

Все здесь дали ответ, основанный на запросе «один запрос». С ними все в порядке. вам нужно использовать case инструкцию И where условие.

Для части вашего вопроса «эффективный способ» вы должны добавить INDEX в login поле, если у вас его еще нет.

Итак, это было бы:

 create index IDX_DANCER_TYPE_LOGIN on DANCER_TYPE(login);
  

И используйте ответ от @SamiKuhmonen

 UPDATE DANCER_TYPE SET TYPE = CASE login
                                WHEN 'arachel' THEN 'BALLET'
                                WHEN 'mandanah' THEN 'EXOTIC_BELLY_DANCER'
                                ...
                                END
                 WHERE login IN ('arachel', 'mandanah', ...);
  

Плюс его объяснение на else

НА МОЙ ВЗГЛЯД, нет more scaleable way затем запустите обновления, разделенные созданным индексом.

Ответ №4:

Определения «лучший», «наиболее масштабируемый» и «наиболее эффективный» могут иметь очень разные значения. Сначала вам нужно их определить. Превосходные степени работают плохо.

Но если вам нужен один запрос, вы можете использовать CASE :

 UPDATE DANCER_TYPE SET TYPE = CASE login
  WHEN 'arachel' THEN 'BALLET'
  WHEN 'mandanah' THEN 'EXOTIC_BELLY_DANCER'
  ...
  END
  WHERE login IN ('arachel', 'mandanah', ...);
  

WHERE Условие, чтобы убедиться, что вы не обновляете ненужные поля. В зависимости от реализации СУБД вам может сойти с рук просто ELSE type и без WHERE условий.

Комментарии:

1. мне нравится условие WHERE там, не думал об этом 🙂

Ответ №5:

Предполагая, что вы используете InnoDB, выполнение UPDATEs в одной транзакции поможет из-за накладных расходов на xaction:

 BEGIN;
UPDATE ...
UPDATE ...
...
COMMIT;
  

Вероятно, использование CASE и WHERE , упомянутых в других ответах, быстрее, чем это.