Почему «LOAD DATA INFILE» быстрее, чем обычные операторы INSERT?

22

Я прочитал статью, в которой упоминалось, что мы можем достичь 60 000 операций вставки в секунду с помощью LOAD DATA IN FILEоператора, который читает файлы CSV и вставляет данные в базу данных.

Почему он должен отличаться от обычных вставок?

РЕДАКТИРОВАТЬ:
я сократил туда-обратно, позвонив только одно INSERTзаявление:

INSERT INTO tblname
VALUES (NULL,2,'some text here0'),(NULL,2,'some text here1')
    ,(NULL,2,'some text here2'),(NULL,2,'some text here3')
    .....,(NULL,2,'some text here3000');

Как насчет этого?

ALH
источник
Я написал статью о среде, бенчмаркинг расширенных вставок против LOAD DATA INFILE: вставок Скоростных с MySQL . Итог: вы можете достичь 65% производительности при LOAD DATA INFILEиспользовании расширенных вставок. Я получил 240 000 вставок в секунду на современном оборудовании.
Бенджамин

Ответы:

26

LOAD DATA INFILE и расширенные INSERT имеют свои отличительные преимущества.

LOAD DATA INFILE предназначен для массовой загрузки табличных данных за одну операцию вместе со наворотами для выполнения таких действий, как:

  • Пропуск начальных строк
  • Пропуск определенных столбцов
  • Преобразование определенных столбцов
  • Загрузка определенных столбцов
  • Обработка повторяющихся ключевых проблем

Для разбора требуется меньше накладных расходов

С другой стороны, если вы импортируете только 100 строк вместо 1 000 000 строк, целесообразно использовать расширенную INSERT.

Обратите внимание, что mysqldump был разработан на основе расширенных INSERT с целью переноса дизайна таблицы вместе с данными, поскольку он выполняет внедрение сотен или тысяч строк на INSERT. LOAD DATA INFILE всегда создает физическую двойственность между схемой и данными.

С точки зрения приложения, LOAD DATA INFILE также более нечувствителен к изменению схемы, чем расширенные INSERT.

Можно пойти взад-вперед по поводу хорошего, плохого и безобразного использования LOAD DATA INFILE. Независимо от того, какую технику вы используете, вы всегда должны устанавливать bulk_insert_buffer_size . Зачем?

В соответствии с документацией MySQL для bulk_insert_buffer_size:

MyISAM использует специальный древовидный кэш, чтобы ускорить массовые вставки для INSERT ... SELECT, INSERT ... VALUES (...), (...), ... и LOAD DATA INFILE при добавлении данных в непустые столы. Эта переменная ограничивает размер дерева кэша в байтах на поток. Установка в 0 отключает эту оптимизацию. Значение по умолчанию составляет 8 МБ.

В течение многих лет я видел, что клиент за клиентом не устанавливал это и оставлял это в 8 МБ. Затем, когда они решат использовать LOAD DATA INFILE или импортировать mysqldumps, они могут почувствовать что-то не так. Я обычно рекомендую установить это умеренное 256M. В некоторых случаях 512M.

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

Честно говоря, выражение LOAD DATA INFILE быстрее, чем обычные операторы INSERT, является своего рода загруженным оператором, главным образом потому, что конфигурация не принимается во внимание. Даже если вы установите эталонный тест между LOAD DATA INFILE и расширенными INSERT с надлежащим параметром bulk_insert_buffer_size, наносекунды, сохраненные при разборе каждой строки, могут дать только номинальные результаты в лучшем случае в пользу LOAD DATA INFILE.

Иди и добавь это в my.cnf

[mysqld]
bulk_inset_buffer_size=256M

Вы также можете установить его только для сеанса, прежде чем запускать расширенные INSERT

SET bulk_insert_buffer_size= 1024 * 1024 * 256;

ОБНОВЛЕНИЕ 2012-07-19 14:58 ПО ВОСТОЧНОМУ ВРЕМЕНИ

Чтобы держать вещи в перспективе, буфер массовой вставки полезен только для загрузки таблиц MyISAM, а не InnoDB. Я написал более свежий пост о массовой загрузке InnoDB: загрузка Mysql из infile застряла в ожидании на жестком диске

RolandoMySQLDBA
источник
4

Большинство систем управления базами данных имеют функцию массовой загрузки для быстрой загрузки больших объемов данных. INSERTЗаявление имеет значительное количество каждого заявления багажа - замок, демаркации транзакций, ссылочную проверку целостности, распределение ресурсов, I / O , что должно быть сделано на основе за заявление.

Массовые операции вставки упрощают процесс, так что у этого материала намного, намного меньше накладных расходов на строку. СУБД может загружать данные на несколько порядков быстрее, чем через операторы вставки.

ConcernedOfTunbridgeWells
источник
3

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

Каждый INSERTоператор должен быть индивидуально проанализирован механизмом MySQL и проверен на правильность - это потребляет дополнительные ресурсы ЦП, а также требует большего количества циклических обращений к клиентскому <> серверу. Этого не должно происходить при массовой загрузке через LOAD DATA INFILE. Есть также оптимизации, которые могут иметь место при использовании LOAD DATA INFILEдля загрузки в пустую таблицу. Смотрите эту ссылку для получения дополнительной информации.

Philᵀᴹ
источник
см редактировать часть моего вопроса.
ALH
Обратите внимание, что при использовании подготовленных операторов нет накладных расходов на синтаксический анализ.
Бенджамин