импортировать объемные данные в MySQL

Поэтому я пытаюсь импортировать некоторые данные о продажах в свою базу данных MySQL. Данные изначально представлены в виде необработанного CSV-файла, который моему PHP-приложению необходимо сначала обработать, а затем сохранить обработанные данные о продажах в базе данных.

Сначала я выполнял отдельные INSERT запросы, которые, как я понял, были невероятно неэффективными (~ 6000 запросов занимали почти 2 минуты). Затем я сгенерировал один большой запрос и сразу INSERTобработал все данные. Это повысило эффективность на 3400 % и сократило время запроса до 3 секунд.

Но насколько я понимаю, LOAD DATA INFILE должен быть даже быстрее, чем любой запрос INSERT. Итак, теперь я думаю о том, чтобы записать обработанные данные в текстовый файл и с помощью LOAD DATA INFILE импортировать их в базу данных. Является ли это оптимальным способом вставки больших объемов данных в базу данных? Или я иду об этом совершенно неправильно?

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

ОБНОВЛЕНИЕ:

Поэтому я пошел дальше и протестировал LOAD DATA INFILE, как было предложено, думая, что это может дать мне лишь незначительное увеличение скорости (поскольку я теперь дважды записывал одни и те же данные на диск), но я был удивлен, когда это сократило время запроса с более чем 3300 мс до ~ 240 мс. Страница по-прежнему занимает примерно ~ 1500 мс для выполнения, но это все еще заметно лучше, чем раньше.

Отсюда, я думаю, я проверю, есть ли у меня лишние индексы в базе данных, и, поскольку все мои таблицы, кроме двух, являются InnoDB, я рассмотрю возможность оптимизации пула буферов InnoDB для оптимизации общей производительности.


person Lèse majesté    schedule 22.06.2010    source источник
comment
Я знаю, что этот вопрос был опубликован много лет назад, но я должен сказать, что разница между одним массовым INSERT и LOAD DATA INFILE заключается в сэкономленном времени. Я перешел от 30 секунд и более с помощью INSERT до примерно 10 секунд, загружая строку ~ 11000 с файлом CSV с 30 столбцами.   -  person CJ Mendes    schedule 19.11.2013


Ответы (4)


LOAD DATA INFILE работает очень быстро и является правильным способом импорта текстовых файлов в MySQL. Это один из рекомендуемых методов для ускорения вставки данных — до 20 раз быстрее, согласно этому:

https://dev.mysql.com/doc/refman/8.0/en/insert-optimization.html

Если предположить, что запись обработанных данных обратно в текстовый файл выполняется быстрее, чем их вставка в базу данных, то это хороший способ.

person Mike    schedule 23.06.2010

ЗАГРУЗИТЬ ДАННЫЕ или несколько вставок будут намного лучше, чем одиночные вставки; ЗАГРУЗИТЬ ДАННЫЕ немного сэкономит вам немного времени, которое вам, вероятно, не очень нужно.

В любом случае, делайте довольно много, но не слишком много за одну транзакцию - 10 000 строк на транзакцию обычно кажется правильным (NB: это не относится к нетранзакционным механизмам). Если ваши транзакции слишком малы, он будет тратить все свое время на синхронизацию журнала с диском.

Большую часть времени большая вставка будет выполняться при построении индексов, что является дорогостоящей операцией с интенсивным использованием памяти.

Если вам нужна производительность,

  • Иметь как можно меньше индексов
  • Убедитесь, что таблица и все ее индексы помещаются в ваш буферный пул innodb (предполагая здесь innodb)
  • Просто добавьте больше оперативной памяти, пока ваша таблица не уместится в памяти, если только это не станет чрезмерно дорогим (64G в настоящее время не слишком дорого).

Если вам необходимо использовать MyISAM, есть несколько грязных приемов, чтобы сделать его лучше, и я не буду обсуждать его дальше.

person MarkR    schedule 23.06.2010

Ребята, у меня был тот же вопрос, мои потребности могли быть немного более конкретными, чем общие, но я написал пост о своих выводах здесь.

http://www.mediabandit.co.uk/blog/215_mysql-bulk-insert-vs-load-data

Для моих нужд загрузка данных была быстрой, но необходимость сохранения в плоский файл на лету означала, что среднее время загрузки занимало больше времени, чем массовая вставка. Более того, мне не нужно было делать больше, чем, скажем, 200 запросов, тогда как раньше я делал это по одному, теперь я их увеличиваю, экономия времени составляет несколько секунд.

В любом случае, надеюсь, это поможет вам?

person Andy    schedule 09.03.2011
comment
Интересно. Это определенно полезно знать для многих случаев использования, хотя я немного смущен тем, как вы получили цифру 0,0013 с. (Я плохо разбираюсь в статистике.) - person Lèse majesté; 10.03.2011
comment
Лезе: Это связано со стандартным отклонением. Насколько я понимаю стандартное отклонение, оно показывает, насколько сильно отличается от среднего. (Excel сделал расчет за меня). Моя точка зрения заключалась в том, что стандартное отклонение для объема было меньше, чем для данных загрузки. Для меня это означало, что BULK всегда был быстрее. Что для меня было самым важным фактором при принятии решения об этом. В основном потому, что это работало на живом сайте. Надеюсь, это имеет смысл? Дополнительную информацию см. здесь: en.wikipedia.org/wiki/Standard_deviation - person Andy; 11.03.2011

Вы должны быть в порядке с вашим подходом. Я не уверен, насколько быстрее LOAD DATA INFILE по сравнению с массовой вставкой, но я слышал то же самое, что это должно быть быстрее.

Конечно, вы захотите провести некоторые тесты, чтобы быть уверенным, но я бы сказал, что стоит написать тестовый код.

person timdev    schedule 23.06.2010