Xpoint
   [напомнить пароль]

Быстрое обновление большого числа записей

Метки: [без меток]
2006-06-03 11:11:02 [обр] Роман Чемисов(0/350)[досье]

Пишу сюда, потому что мой вопрос/проблема (как я понимаю) находится на стыке программирования и БД.
Программирую я на Perl, а БД у меня MySQL. Теперь о том, что меня беспокоит :-).
Мне необходимо быстро обновлять большое количество записей (по два поля на каждую запись). К тому же каждую запись я выбираю по двум параметрам (их комбинация уникальна). Т. е. у меня примерно такой запрос:

UPDATE tbl_results SET result = ?, final = ? WHERE (bid_num = ? AND site_id = ?);

Если к этому прибавить то, что делается это всё сейчас в цикле и для каждой записи в отдельности, то получатся жуткие тормоза (на 100 записей уходит от 170 до 200 секунд)
Вообщем вопрос в том, как такие вещи правильно делать? Может вынести обновляемы поля в отдельную таблицу и вместо обновления делать INSERT?
P. S. Таблица, в которой надо обновлять поля, большая (и каждый день увеличивается примерно на 30000 записей).

спустя 7 часов [обр] Владимир Палант(27/4445)[досье]
В первую очередь надо удостовериться, что в базе есть индекс по комбинации полей bid_num и site_id. Если при этом такой тип выборки типичен, что лучше сделать этот индекс основным.
спустя 1 час 20 минут [обр] Роман Чемисов(0/350)[досье]
Владимир Палант[досье]
Ну, с индексами всё понятно. А ещё что можно придумать?
спустя 5 часов [обр] Илья Cтpeльцын aka SelenIT(0/171)[досье]

Имхо, все же обновлять каждую запись отдельным запросом - нерационально. Может, есть смысл попробовать что-то наподобие такого?

UPDATE tbl_results 
SET 
result = CASE site_id
   WHEN значение_1 THEN что-то_1
   WHEN значение_2 THEN что-то_2
   ...
   WHEN значение_n THEN что-то_n
END,
final = CASE site_id
   WHEN значение_1 THEN еще_что-то_1
   WHEN значение_2 THEN еще_что-то_2
   ...
   WHEN значение_n THEN еще_что-то_n
END
WHERE (bid_num = значение_i AND site_id IN (значение_1,значение_2,...значение_n));

Причем цикл можно делать по параметру с меньшим диапазоном значений, чтобы каждый запрос давал большую результативность (влиял на большее количество записей). Теоретически, подобным образом можно обновить все одним гигантским запросом, но это, наверное, уже другая крайность.

спустя 11 часов [обр] Андрей Гора(0/29)[досье]
Как-то медленно у Вас происходит UPDATE, тут можно что-то поискать.
  1. Если result и final - индексы, то ... может не так они обязательны, раз такое дело?
  2. Если таблица с динамическим форматом result и final, то OPTIMIZE TABLE может дефрагментировать файл.
  3. Если одновременно это таблица задействавана в чем-то другом (что может объяснить медленные запросы), то хорошим делом будет ее блокирование перед циклом, в таком случае цикл следует мастырить быстрым, т.е. предваряющие UPDATE расчеты, если есть, производить до его запуска.
спустя 2 часа 41 минуту [обр] Роман Чемисов(0/350)[досье]
Спасибо всем ответившим.
Я убрал лишние запросы в цикле (оставив только UPDATE), плотнее поработал над индексами и сейчас скорость меня в принципе устраивает (около 15 записей в секунду и это грязное время, т. е. туда входит время получения страницы и её парсинг).
спустя 4 дня [обр] Закиров Руслан(0/343)[досье]
Что бы индекс использовался на полную катушку, он должен быть составным.
спустя 59 минут [обр] Роман Чемисов(0/350)[досье]
Закиров Руслан[досье]
У меня сейчас как раз составной индекс: bid_num + site_id (на самом деле он даже из трёх частей сейчас состоит).
Powered by POEM™ Engine Copyright © 2002-2005