2017-01-13 2 views
1

Так я написал скрипт, который импортировать данные из CSV-файла с более чем 1,5 млн строк в таблицу MySQL InnoDB, он будет сканировать CSV, то для каждого CSV строки:Slow вставки и обновления в большой таблице

  • Искать в таблице, чтобы проверить, существует ли запись.
  • Если существует, обновите запись.
  • Если нет, вставьте новый.

Затем перейдите к следующей строке в CSV и выполните вышеуказанные шаги еще раз.

Проблема заключается в том, что таблица, данные которой будут импортированы, также имеет 1,5 м записи, что делает ее слишком медленной для импорта данных. Я попробовал сценарий и увидел, что:

  • Если данные импортируются в пустую таблицу, он может импортировать 500 строк в минуту.
  • Если импортировать данные в эту таблицу записей 1,5 м, она может импортировать только 30 строк в минуту.

Есть ли какое-либо решение для ускорения импорта?

+2

Возможно, заменить 3 шага одной «вставкой в ​​... при повторном обновлении ключа ...». 'INSERT' уже выполняет повторную проверку ключа, делая вашу собственную проверку избыточной. – apokryfos

+0

может убрать показать структуру таблицы? –

+0

Вам нужно привести пример, например 'SHOW CREATE TABLE', который забирает вашу таблицу и связанные индексы. Как пишет @apokryfos, «ON DUPLICATE KEY» - настоящее решение здесь, он делает все за один шаг, беспорядок. Вы даже можете вставить непосредственно из файла CSV. – tadman

ответ

0

Корень проблемы заключается в следующем:

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

Это означает, что СУБД будет (помимо всего прочего) искать элемент, когда вы выполняете INSERT, делая ваш более ранний поиск избыточным.

Вы можете заменить 3 операции ни с одной, которая будет выглядеть примерно так:

INSERT INTO tablename(column1,column2...) 
VALUES (v1,v2,....) 
ON DUPLICATE KEY UPDATE SET column1=v1... 

Также полезно, чтобы знать, что если вы говорите, column1=VALUES(column1) это означает «использовать значение, которое я указал в VALUES() часть вставки.

+0

Спасибо! Используя это решение, скорость импорта значительно увеличилась с 30 заказов/мин до 4000 заказов в минуту! Для получения дополнительной информации, когда таблица настолько велика, если вы используете запрос «SELECT WHERE», для ее выполнения потребуется 6-9 минут (6 секунд), и это проблема. Я думаю, что элемент «Вставить на дубликат» просто вставляет строку без проверки и превращается в запрос «update», если возвращается повторяющееся исключение. – mee