MySql ОБНОВЛЕНИЕ оптимизации? - PullRequest
5 голосов
/ 14 января 2011

Давайте предположим, что у меня есть таблица с двумя столбцами A и B. Существует индекс для столбца A, но не для столбца B. Я хочу выполнить несколько миллионов запросов, таких как:

UPDATE t1 SET b=b1 WHERE a=a1;
UPDATE t1 SET b=b2 WHERE a=a2;
....

Естьот 1 до 100 000 строк, соответствующих каждому уникальному значению a.В среднем это около 100.

Для каждого оператора обновления в среднем 60% строк не будут изменены, потому что для этих строк b уже имеет желаемое значение.Для 30% обновлений ни одна из подходящих строк не будет изменена.

Имеет ли смысл использовать подобные операторы?

UPDATE t1 SET b=b1 WHERE a=a1 AND b<>b1;

Ускорит ли это процесс за счет устранения ненужных обратных записейдиск или Mysql 5 достаточно умен, чтобы признать, что ничего не меняется и нет необходимости записывать обратно на диск?

Ответы [ 3 ]

4 голосов
/ 14 января 2011

В любом случае MySQL должен будет прочитать содержимое строки (будь то на диске или в кеше / буферном пуле).В любом случае MySQL будет использовать ваш индекс a в качестве отправной точки.В любом случае MySQL не будет обновлять строку, если она уже имеет целевое значение для b.Следовательно, я не вижу никакого способа, которым MySQL выиграет от предложения b<>b1.

Возможно, в зависимости от рабочей нагрузки и набора данных запрос (с b<>b1 в нем) может выиграть, если вы измените свой индекс на a на составной индекс на a и b (в таком порядке).В этом случае не нужно было бы нажимать на диск (или проверять пул кеша / буфера), чтобы найти, какие строки , в частности требуют обновления (т.е. вы заработали бы на 30% и 60%, которые вы упомянули),Сказав это, теперь ваш индекс будет требовать обновления для каждого обновления на b, поэтому стоит стоимость, хотя я подозреваю, что компромисс может стоить.

0 голосов
/ 14 января 2011

Я думал объединить несколько обновлений в одно обновление, используя CASE

update t1
set b=
  case a
    when a=a1 then b1
    when a=a2 then b2
    when a=a3 then b3 ...
  end;

надеюсь, что это полезно, и если это ужасно медленно, пожалуйста, включите объяснение

0 голосов
/ 14 января 2011

Вы должны добавить дополнительный фильтр. Mysql достаточно умен, чтобы не обновлять значение, если оно совпадает, но лучше убрать эту проверку. В этом можно убедиться, посмотрев, сколько строк «затронуло» запрос.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...