Insert..Выбирать в таблицу InnoDB с фиксацией после каждой вставки? - PullRequest
1 голос
/ 06 мая 2011

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

Просто чтобы прояснить: OldTable - это MyISAM. NewTable - это InnoDB и разделена по диапазону по первичному ключу 'a'. Обе таблицы имеют одинаковые имена полей. Сами поля не идентичны, но там, где они различаются, поля в NewTable больше.

Запрос, вызывающий проблемы, выглядит следующим образом:

INSERT INTO NewTable (a,b,c,d,e,f,g) 
SELECT a,b,c,d,e,f,g 
FROM OldTable 
WHERE a > 300000000 AND a <= 400000000
order by a

Что бы я хотел, чтобы он делал: либо фиксировал после каждой вставки, либо просто полностью отказывался от целостности транзакции и позволял бы выполнять грязное чтение, если оно происходит.

Блокировка NewTable (кроме, возможно, одной вставляемой строки) недопустима. Блокировка OldTable - это хорошо, потому что в любом случае ее больше никто не использует (конечно, кроме SQL, чтобы скопировать ее в новую таблицу).

Кроме того, есть ли способ заставить MySQL делать это с наименьшим возможным приоритетом и работать над задачей только в свое (относительное) свободное время?

1 Ответ

1 голос
/ 09 мая 2011

Помимо уменьшения количества строк, вставляемых за раз, попробуйте увеличить значение системной переменной bulk_insert_buffer_size до значения, более подходящего для вашего случая?Значение по умолчанию составляет 8 МБ.

...