Чому "LOAD DATA INFILE" швидше, ніж звичайні заяви INSERT?


22

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

Чому він повинен відрізнятися від звичайних вставок?

EDIT:
Я скоротив зворотну поїздку, зателефонувавши лише до одного 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');

Як що до цього?


Я написав статтю про Medium, порівняльний аналіз розширених вставок vs LOAD DATA INFILE: Високошвидкісні вставки з MySQL . Підсумок: ви можете домогтися 65% продуктивності LOAD DATA INFILEвикористання розширених вставок. Я отримав 240 000 вставок / секунду на сучасному обладнанні.
Бенджамін

Відповіді:


26

ІНФІЛЬ ЗАВАНТАЖЕННЯ ДАНИХ та розширені ВСТАВКИ мають різні переваги.

ІНФАЙЛ НАВАНТАЖЕННЯ ДАНИХ призначений для масового завантаження даних таблиці за одну операцію разом із дзвіночками та дзвінками для виконання відтінків, таких як:

  • Пропуск початкових ліній
  • Пропуск конкретних стовпців
  • Перетворення конкретних стовпців
  • Завантаження конкретних стовпців
  • Поводження з повторюваними ключовими проблемами

Для розбору потрібно менше накладних витрат

З іншого боку, якщо ви імпортуєте лише 100 рядків замість 1 000 000 рядків, розширений INSERT є розумним.

Зауважте, що mysqldump був розроблений навколо розширених INSERT для перенесення таблиці таблиці разом із даними, оскільки вона виконує введення сотень чи тисяч рядків у INSERT. ЗАВАНТАЖЕННЯ ДАНИХ INFILE завжди створює фізичну дихомотику між схемою та даними.

З точки зору програми, ЗАВАНТАЖЕННЯ ДАНИХ ІНФІЛЕЙ також є більш нечутливим до зміни схеми, ніж розширені ВСТАВКИ.

Можна використовувати вперед і назад про хороше, погане та потворне використання ЗАВАНТАЖЕННЯ ДАННИХ ІНФІЛІЙ. Незалежно від того, якою технікою ви користуєтесь, ви завжди повинні встановлювати розмір bulk_insert_buffer_size . Чому?

Відповідно до документації MySQL на bulk_insert_buffer_size:

MyISAM використовує спеціальний кешоподібний кеш для того, щоб зробити масові вставки швидшими для INSERT ... SELECT, INSERT ... VALUES (...), (...), ..., and LOAD DATA INFILE при додаванні даних до непустих столи. Ця змінна обмежує розмір дерева кеша в байтах на потік. Встановлення його на 0 відключає цю оптимізацію. Значення за замовчуванням - 8 МБ.

Протягом багатьох років я бачив, як клієнт після того, як клієнт не встановив цього, залишив його на рівні 8 МБ. Потім, коли вони вирішать використовувати ЗАВАНТАЖЕННЯ ДАНИХ INFILE або імпортувати mysqldumps, вони можуть відчути щось не так. Зазвичай я рекомендую встановити це на помірний 256 Мб. У деяких випадках 512М.

Після того, як у вас є достатньо великий об'ємний буфер INSERT, використання будь-якої техніки стає академічною і зводиться до особистого вибору. Для додатків, де ви набираєте INSERT лише 100 рядків на вимогу, дотримуйтесь розширених INSERT.

Справедливості, кажучи, що LOAD DATA INFILE швидше, ніж звичайні оператори INSERT є певним чином завантаженим оператором, головним чином тому, що конфігурація не враховується. Навіть якщо ви встановите орієнтир між INFILE ЗАВАНТАЖЕННЯ ДАНИХ та розширеними INSERT з належним bulk_insert_buffer_size, наносекунди, збережені при розборі кожного ряду, можуть давати лише номінальні результати в кращому випадку на користь ЗАВАНТАЖЕННЯ ДАНИХ INFILE.

Вперед і додайте це до my.cnf

[mysqld]
bulk_inset_buffer_size=256M

Ви також можете встановити його лише для свого сеансу перед запуском розширених INSERT

SET bulk_insert_buffer_size= 1024 * 1024 * 256;

ОНОВЛЕННЯ 2012-07-19 14:58 EDT

Щоб зберегти речі в перспективі, буфер масової вставки корисний лише для завантаження таблиць MyISAM, а не InnoDB. Я написав останній пост про масове завантаження InnoDB: завантаження Mysql з інфіле застрягло, чекаючи на жорсткому диску


4

Більшість систем управління базами даних мають засоби масового навантаження для швидкого завантаження великих обсягів даних. AnINSERT виписці є значна кількість багажу за випискою - блокування, розмежування транзакцій, референтна перевірка цілісності, розподіл ресурсів, введення / виведення, що повинно здійснюватися на основі заяви.

Операції масової вставки оптимізують процес, так що цей матеріал має значно, значно менше накладних витрат на ряд. СУБД може масово завантажувати порядок передачі даних швидше, ніж через вставлення операторів.


3

Розбір та виконання окремих INSERTвисловлювань має набагато більший накладні витрати, ніж розділення файлу CSV на стовпці та безпосередньо їх завантаження.

Кожен INSERTоператор повинен бути індивідуально проаналізований механізмом MySQL та перевірений на надійність - це вимагає додаткових ресурсів процесора, а також вимагає більше клієнтських <> серверних обходів. Цього не потрібно робити при масовому завантаженні через LOAD DATA INFILE. Існують також оптимізації, які можуть мати місце під час LOAD DATA INFILEзавантаження в порожню таблицю. Для отримання додаткової інформації див. Це посилання .


дивіться частину мого запитання EDIT.
ALH

Зауважте, що при використанні підготовлених операторів не існує синтаксичного аналізу.
Бенджамін
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.