Pull to refresh

Особенность оптимизатора MySQL 5.1.30 порядок следования таблиц в UPDATE

Reading time1 min
Views967
Добрый день. Я расскажу об одной из забавных особенностей оптимизатора MySQL 5.1.30, которая заставляет перед обновлением внимательно проверить запросы.
Для любопытных: «теперь SET-выражения выполняются не в порядке следования выражений слева направо, а в порядке следования обновляемых таблиц».


Хочу сразу же сказать, что автором топика я не являюсь, а является travisbickle. Он не смог опубликовать пост из-за низкой кармы — так что все благодарности туда.

Как любой бдящий админ, я в очередной раз обновился, потыкался в разные места и решил что всё работает.
Прошел месяц и сегодня я узрел в месячном чарте рейтингов за январь одни нули…
За операцию перевода текущего рейтинга в месячный и в суммарный отвечает простенький запрос, который запускается раз в сутки
UPDATE
  xE_tvchannels_dyn AS t0,
  xE_tvchannels_monthrating AS t1
SET
  t0.ratingflushed = 1233522000,
  t1.rating = t1.rating + t0.rating,
  t0.totalrating = t0.totalrating + t0.rating,
  t0.rating = 0
WHERE
  t0.id = t1.cid AND
  t1.month = '200902' AND
  t0.rating > 0 AND
  t0.ratingflushed <1233522000


* This source code was highlighted with Source Code Highlighter. maxshopen

Причина оказалось прозаична — теперь SET-выражения выполняются не в порядке следования выражений слева направо, а в порядке следования обновляемых таблиц, таким образом данный запрос честно выполнял `t0`.`ratingflushed` = 1233522000, `t0`.`rating` = 0, и только потом `t1`.`rating` = `t1`.`rating` + `t0`.`rating`.

Вылечилось, разумеется UPDATE `xE_tvchannels_monthrating` AS `t1`, `xE_tvchannels_dyn` AS `t0`

Будьте внимательны, товарищи!
Tags:
Hubs:
Total votes 45: ↑43 and ↓2+41
Comments16

Articles