InnoDB вставка быстрее

8

Я аспирант, изучающий OLAP с Мондрианом OLAP. Поэтому я хочу вставить данные в InnoDB (MySQL 5.5) быстрее при начальной загрузке. В этой среде единственным пользователем является я, поэтому я думаю, что может позволить более свободные настройки для скорости вставки. На данный момент я использую следующие приемы.

  • отключить log_bin
  • включить skip-innodb-doublewrite
  • установить transaction_isolationна READ-COMMITTEDили READ-UNCOMMITTED( на самом деле READ-COMMITED)
  • установить innodb_flush_log_at_trx_commitна 0или 2( на самом деле 0)
  • установить innodb_buffer_pool_size5 ГБ (в системе 6 ГБ ОЗУ)

Есть ли еще методы для более быстрой вставки в InnoDB? И нужно ли модифицировать innodb_io_read_threadи innodb_io_write_thread? Если вам нужна дополнительная информация, пожалуйста, скажите мне.

inohiro
источник

Ответы:

9

ПРЕДЛОЖЕНИЕ № 1

Если ваша машина имеет несколько ядер, вам нужно увеличить следующее:

[mysqld]
innodb_read_io_threads = 64
innodb_write_io_threads = 64
innodb_io_capacity = 5000

Что это?

  • innodb_read_io_threads - количество потоков ввода-вывода для операций чтения в InnoDB.
  • innodb_write_io_threads - количество потоков ввода-вывода для операций записи в InnoDB.
  • innodb_io_capacity - верхний предел активности ввода-вывода, выполняемой фоновыми задачами InnoDB, такими как очистка страниц из пула буферов и объединение данных из буфера вставки.

ПРЕДЛОЖЕНИЕ № 2

Чтобы отделить данные и индексы от системного табличного пространства (ibdata1), необходимо выполнить полную реструктуризацию InnoDB. Звучит сложно, но очень просто. Я писал об этом в DBA StackExchange (29 августа 2012 г.) и в StackOverflow (29 октября 2010 г.) . Основные шаги

  • Запустить SET GLOBAL innodb_fast_shutdown = 0;
  • mysqldump все данные в дамп SQL
  • service mysql stop
  • Удалить следующие файлы
    • ibdata1
    • ib_logfile0
    • ib_logfile1
  • service mysql start

Перед запуском service mysql startдобавьте эту строку вmy.cnf

innodb_open_files=32768

Таким образом, будут файловые дескрипторы, предназначенные для каждой отдельной таблицы. Значение по умолчанию - 300. Известно, что файловые дескрипторы кэшируются. Будет замедление, если вы установите это очень высоко и быстро достигнете потолка . Это не должно иметь место, если вы работаете с небольшим количеством таблиц.

RolandoMySQLDBA
источник
Спасибо вам за ваши предложения. Постараюсь рекомендации № 2 прямо сейчас, и я буду корректировать innodb_read_io_threads, innodb_write_io_threadsи `innodb_io_capacity.
Инохиро
«Удалить следующие файлы ibdata1» Sheesh, без предупреждения.
Магалланес
6

Есть целый документ, посвященный массовой загрузке данных в InnoDB. Основные моменты:

  1. отключите автокоммит, чтобы избежать дополнительной очистки журнала для каждого оператора вставки: SET autocommit=0;...sql import;COMMIT;
  2. отключите внешние и уникальные проверки (вы не можете полностью отключить все индексы):

    SET unique_checks=0;
    SET foreign_key_checks=0;
  3. Потенциально установите innodb_autoinc_lock_mode в 2 вместо 1 (по умолчанию). Вот документация по этому параметру.

Третий может или не может помочь вам, поэтому я предлагаю прочитать эту ссылку, чтобы увидеть, как вы изначально загружаете данные. Например, если вы разбиваете нагрузку на несколько вставок для одновременного запуска, это определенно поможет вам установить значение 2. Если вы выполняете одну большую многострочную вставку, она не будет делать много (если вообще что-то) для Помогите.

Поскольку вы обращаетесь к двоичному журналу для этой начальной вставки, вам не следует беспокоиться о пробелах в числах автоинкремента (если выполняются параллельные вставки).

Дерек Дауни
источник
Спасибо за ваш ответ! Массовая вставка выглядит так быстро, а я попробую позже.
Инохиро
Просто установка autocommit = 0 увеличивается, хотя и на порядки. Спасибо!
Алекс Баркер
1

Вы можете использовать следующие методы для ускорения вставки:

  • Если вы вставляете много строк из одного и того же клиента одновременно, используйте INSERTоператоры с несколькими VALUESсписками, чтобы вставить несколько строк одновременно. Это значительно быстрее (во многих случаях быстрее), чем использование отдельных однострочных INSERTоператоров. Если вы добавляете данные в непустую таблицу, вы можете настроить переменную bulk_insert_buffer_size, чтобы сделать вставку данных еще быстрее.
  • При загрузке таблицы из текстового файла используйте LOAD DATA INFILE. Обычно это в 20 раз быстрее, чем с помощью INSERTоператоров. Видеть
  • Воспользуйтесь тем, что столбцы имеют значения по умолчанию. Вставьте значения явно только тогда, когда значение, которое будет вставлено, отличается от значения по умолчанию. Это уменьшает разбор, который должен выполнять MySQL, и повышает скорость вставки.
  • См. Раздел 9.5.5, « Массовая загрузка данных для таблиц InnoDB », где приведены советы, относящиеся к таблицам InnoDB.
user2432735
источник
0

План A: «Пакетные» INSERT - несколько строк на оператор INSERT. Предложите около 1000 строк на утверждение. autocommit = on, нет явного BEGIN ... COMMIT

План Б: ЗАГРУЗИТЬ ДАННЫЕ

Если вы вставляете слишком много строк одновременно, InnoDB должен выполнить больше работы, чтобы иметь возможность откатить вставку в случае сбоя. По этой причине я не согласен с autocommit = off, который помещает весь набор в одну транзакцию.

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

buffer_pool = 5G из 6G находится на грани слишком большого. Если произойдет обмен, производительность упадет.

РАЗДЕЛЕНИЕ, вероятно, сделает это медленнее.

SHOW CREATE TABLE - дополнительные ключи могут быть серьезным препятствием.

Вы используете InnoDB? или XtraDB?

Рик Джеймс
источник
Спасибо за ваш ответ. Я использую InnoDB. Я предпочитаю, чтобы план A, а не план B. LOAD DATAвыглядели так быстро, но нам нужно записать данные в текст сразу как CSV, а затем использовать LOAD DATAправильно? / Я установлю buffer_pool_size4 ГБ.
Инохиро