Очень разное время выполнения для обновления в разных системах MySQL.

У меня очень странная ситуация с MySQL.

Возьмем следующий пример: таблица, содержащая 15000 записей.

CREATE TABLE `temp_geonis_export` (
`auto_id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, 
`obj_id` VARCHAR(10),
`gis_id` VARCHAR(45),
`letzteReinigung_id` VARCHAR(10),
INDEX `Index_2`(`gis_id`),
PRIMARY KEY (`auto_id`)
)
ENGINE = InnoDB;

Сейчас я обновляю 14000 строк в таблице. Я знаю, это довольно уродливое утверждение, которое можно было бы легко переписать, но вопрос не в этом...

Update temp_geonis_export as temp
inner join (
Select gis_id, obj_id from 
(
Select abw.gis_id, abw.bezeichnung, erh.obj_id
from od_abwasserbauwerk as abw
inner join od_erhaltungsereignis as erh on erh.fs_abwasserbauwerk = abw.obj_id and erh.status = 2
inner join od_reinigung as unter on unter.obj_id = erh.obj_id
order by fs_abwasserbauwerk asc, erh.zeitpunkt asc
) as alleSortiert group by alleSortiert.gis_id
) as naechsteRein on temp.gis_id = naechsteRein.gis_id
set temp.naechsteReinigung_id = naechsteRein.obj_id;

Теперь, если я запускаю оператор обновления на нашем сервере разработки, это занимает около 1 секунды. На одном из наших производственных серверов это занимает 90 секунд!!

Это мои наблюдения:

  • Handler_read_rnd_next 101000 (разработка), 266177000 (производство)
  • Очень высокая загрузка ЦП в производственной системе (из-за приведенного выше наблюдения)
  • Почти нет дискового ввода-вывода в обеих системах
  • Когда я переписываю Update-Query и сохраняю вывод подзапроса во временную таблицу, Update-Statement выполняется быстро в обеих системах.

Due to the observations my conclusion is, that for some reason, our production server has to perform full table scans for each updated row. The development server does not. It must be a configuration issue, since our Servers are all 5.1.25 and the hardware is comparable.

Do you have a clue, what I have to change on our production server to make it perform better?

Спасибо за вашу помощь


person klib009    schedule 26.06.2013    source источник
comment
Отправьте EXPLAINs для вашего запроса как с серверов разработчиков, так и с рабочих серверов.   -  person peterm    schedule 26.06.2013
comment
peterm, AFAIK, EXPLAIN Обновление доступно только с версии MySQL 5.6. Я могу использовать его только для подзапроса. Подзапрос (Select) хорошо работает в обеих системах.   -  person klib009    schedule 26.06.2013
comment
Измените UPDATE на SELECT, чтобы сделать объединение, которое используется в обновлении, откажитесь от предложения SET и объясните запрос в обеих средах и опубликуйте его.   -  person peterm    schedule 26.06.2013
comment
Спасибо за подсказку! По неизвестной причине я не могу загружать изображения в свой вопрос, поэтому я загрузил их здесь: Разработка: ссылка Производство: ссылка   -  person klib009    schedule 26.06.2013
comment
Вам лучше выполнить EXPLAIN в mysql (в командной строке) и опубликовать текстовый вывод. Было бы намного читабельнее. Теперь, как вы можете видеть, у вас нет всех необходимых индексов в производственной среде.   -  person peterm    schedule 26.06.2013
comment
петерм, спасибо за подсказку. в следующий раз выложу текстовый вывод из командной строки. Я понимаю, что у запроса нет индексов, но почему? Я попытался создать индекс с помощью ALTER TABLE вместо создания его с помощью CREATE TABLE, но это не меняет проблему. Я также отправил производственную БД в разработку (как схему, так и данные). Опять же, в среде разработки используется индекс   -  person klib009    schedule 26.06.2013
comment
Exec DESC tablename и SHOW INDEX FROM tablename для всех ваших таблиц, которые используются в вашем запросе в обеих средах, и сравните их. Я предполагаю, что вы что-то упускаете.   -  person peterm    schedule 26.06.2013


Ответы (1)


Через несколько часов я, наконец, нашел решение:
Проблема заключалась в том, что НАБОР ПО УМОЛЧАНИЮ на рабочем сервере отличался от набора символов, используемого в базе данных. Теперь при создании таблицы без явного указания кодировки MySQL не использовал индексы. Это связано с тем, что MySQL не может использовать индексы для CHAR-полей, когда наборы символов соединяемых таблиц различаются.

Большое спасибо за помощь, петерм. Вы указали мне правильное направление.

person klib009    schedule 26.06.2013