Как скопировать миллионы строк из одной таблицы в другую?
Есть задача на проде, скопировать миллионы строк из одной таблицы в другую, проверяя при вставке есть ли такая запись. Очень важна производительность, чтобы запрос не выполнялся несколько часов. Структура таблиц, набор полей разные.
Первое что приходит в голову:
1) Написать миграцию на doctrine, скорее всего будет очень медленно
2) Написать SQL запрос, который запустить в консоли, что чревато из за долго выполнения, особенно если там будут подзапросы
3) Ограничить количество обрабатываемых записей за раз, добавить лимит или пакетную обработку
4) Использовать какие то встроенные инструменты копирования, бэкапа.
Задача из разряда "У меня в подполе происходит стук"...
на проде, скопировать миллионы строк из одной таблицы в другую
Таблицы - в рамках одной БД? одного инстанса MySQL? Одного хоста? Одного гипервизора? иное?
Размер одной записи? соответственно общий объём к копированию/переносу?
проверяя при вставке есть ли такая запись.
Полная проверка записи? по значению выражения первичного или некоего уникального индекса? По значению иного выражения? или критерий дублирования - множественный? в последнем случае - все ли варианты выражений индексированы?
Структура таблиц, набор полей разные.
Имеется ли полная поддержка значениями по умолчанию для полей, отсутствующих в копируемой структуре?
И о ненаписанном - имеются ли на целевой таблице триггеры? имеются ли в ней CHECK CONSTRAINT / Foreign key, способные вызвать violation безотносительно к дублированию данных в рамках заданного критерия дублирования?
https://www.w3schools.com/sql/sql_insert_into_sele...
В зависимости от того насколько разные таблицы и какие поля NOT NULL может понадобиться заполнение какими-то данными. На малой выборке нужно сначала отладить запрос SELECT с необходимыми трансформациями и индексами. Как только SELECT будет работать исправно для разных случаев, запустить частичную миграцию, проверив как получается. Потом, опустошив целевую таблицу с TRUNCATE TABLE, запустить полную миграцию через Doctrine, при условии, что умеет генерировать подобный запрос корректно, конечно.
На миллионах будет работать нормально.
Думаю, лучше IGNORE, так как при OR UPDATE будет либо вставлять, либо обновлять — одно из двух. Тогда как при IGNORE будет только вставлять и пропускать ненужное.