Любой INSERT ... SELECT ...
запрос получает блокировку SHARED для строк, которые он читает из исходной таблицы в SELECT. Но при обработке небольших кусков строк блокировка не длится слишком долго.
Запрос с LIMIT ... OFFSET
будет выполняться все медленнее и медленнее по мере продвижения по исходной таблице. При 10000 строк на блок необходимо выполнить этот запрос 10000 раз, каждый из которых должен начинаться заново и сканировать таблицу, чтобы достичь нового СМЕЩЕНИЯ.
Независимо от того, что вы делаете, копирование 100 миллионов строк займет некоторое время. Это делает много работы.
Я бы использовал pt-archiver , бесплатный инструмент, разработанный для этой цели. Обрабатывает строки в «чанках» (или подмножествах). Он будет динамически регулировать размер чанков, чтобы каждый чанк занимал 0,5 секунды.
Самым большим отличием вашего метода от pt-archiver является то, что pt-archiver не использует LIMIT ... OFFSET
, он идет по индексу первичного ключа, выбирая куски строки по значению, а не по положению. Таким образом, каждый кусок читается более эффективно.
Ваш комментарий:
Я ожидаю, что уменьшение размера пакета и увеличение количества итераций приведет к снижению производительности хуже , а не лучше.
Причина в том, что когда вы используете LIMIT
с OFFSET
, каждый запрос должен начинаться с начала таблицы и считать строки до значения OFFSET
. Это становится все длиннее и длиннее, когда вы перебираете таблицу.
Выполнение 20 000 дорогих запросов с использованием OFFSET
займет больше времени, чем 10 000 похожих запросов. Самая дорогая часть не будет читать 5000 или 10000 строк или вставлять их в таблицу назначения. Дорогая часть будет пропускать ~ 50 000 000 строк снова и снова.
Вместо этого вам следует перебирать таблицу по значениям , а не по смещениям.
INSERT IGNORE INTO Table2(id, field2, field3)
SELECT f1, f2, f3
FROM Table1
WHERE id BETWEEN rowOffset AND rowOffset+limitSize;
Перед циклом запросите значения MIN (id) и MAX (id), и начните rowOffset
с минимального значения и выполните цикл до максимального значения.
Так работает pt-архиватор.