Я часто пишу datascrubs, которые обновляют миллионы строк данных. Данные хранятся в базе данных OLTP MySQL 24x7x365 с использованием InnoDB. Обновления могут счищать каждую строку таблицы (в которой БД заканчивается приобретением блокировки на уровне таблицы) или может просто очищать 10% строк в таблице (которая все еще может быть в миллионах).Операция MySQL UPDATE, чтобы избежать массивных размеров TRX
Чтобы избежать создания массивных размеров транзакций и минимизации конкуренции, я обычно пытаюсь разбить мой один массивный оператор UPDATE на ряд небольших транзакций UPDATE. Так что я в конечном итоге писать циклическую конструкцию, которая ограничивает мой UPDATE, где положение так:
(предупреждение: это просто псевдо-код, чтобы получить точку в поперечнике)
@batch_size=10000;
@max_primary_key_value = select max(pk) from table1
for (int i=0; i<[email protected]_primary_key_value; [email protected]_size)
{
start transaction;
update IGNORE table1
set col2 = "flag set"
where col2 = "flag not set"
and pk > i
and pk < [email protected];
commit;
}
Такой подход просто отстой так много причин.
Я хотел бы выпустить инструкцию UPDATE без базы данных, которая пытается сгруппировать все обновляемые записи в единый блок транзакций. Я не хочу, чтобы UPDATE преуспел или потерпел неудачу как единое целое. Если 1/2 строки не обновляются ... нет проблем, просто дайте мне знать. По сути, каждая строка - это собственная единица работы, но дозирование или курсор - единственный способ понять, как представить это для механизма базы данных.
Я рассмотрел установки уровней изоляции для своей сессии, но это, похоже, не помогает мне в этом конкретном случае.
Любые другие идеи?
Интересный подход Эрик. Мне нравится идея, но она ограничена обновлениями, которые фактически изменяют значения полей, которые заданы в предложении WHERE (например, в примере, который я дал). Однако у меня такая же проблема с большими обновлениями, которые не соответствуют этому шаблону (например, установите col1 = "foo", где col2 = "bar"). – 2010-01-06 15:10:58
@Matthew - если это так, вы всегда можете изменить свой запрос, чтобы быть чем-то вроде «set col1 = 'foo», где col2 = «bar» и col1! =' Foo », что позволило бы избежать проблемы с пакетом non -модулирование обновлений, выбивающих вас из цикла. –