InnoDB занимает более часа, чтобы импортировать файл размером 600 МБ, MyISAM за несколько минут - PullRequest
54 голосов
/ 30 января 2010

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

Я готовлюсь протестировать один и тот же дамп данных с MySQL и InnoDB, но мне уже не удается довести начальный импорт до приемлемой скорости для части InnoDB. Первоначальный дамп занял больше времени, но меня это еще не касалось:

$ for i in testdb_myisam testdb_innodb; do time mysqldump --extended-insert $i > $i.sql; done

real    0m38.152s
user    0m8.381s
sys     0m2.612s

real    1m16.665s
user    0m6.600s
sys     0m2.552s

Однако время импорта было совсем другим:

$ for i in  testdb_myisam testdb_innodb; do time mysql $i < $i.sql; done

real    2m52.821s
user    0m10.505s
sys     0m1.252s

real    87m36.586s
user    0m10.637s
sys     0m1.208s

После исследования я пришел за Изменение таблиц с MyISAM на InnoDB замедляет работу системы , а затем используется set global innodb_flush_log_at_trx_commit=2:

$ time mysql testdb_innodb < testdb_innodb.sql

real    64m8.348s
user    0m10.533s
sys     0m1.152s

ИМХО по-прежнему шокирующе медленно. Я также отключил log_bin для этих тестов, и вот список всех переменных mysql .

Должен ли я принять это долгое время InnoDB или они могут быть улучшены? Я полностью контролирую этот сервер MySQL, поскольку он предназначен исключительно для этой тестовой среды.

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

Обновление:

С учетом обратной связи я отключил автокоммит и различные проверки:

$ time ( echo "SET autocommit=0; SET unique_checks=0; SET foreign_key_checks=0;" \
; cat testdb_innodb.sql ; echo "COMMIT;" ) | mysql testdb_innodb;date

real    47m59.019s
user    0m10.665s
sys     0m2.896s

Скорость улучшилась, но не так сильно. Мой тест некорректен?

Обновление 2:

Мне удалось получить доступ к другой машине, где импорт занял всего около 8 минут. Я сравнил конфигурации и применил следующие настройки к моей установке MySQL:

innodb_additional_mem_pool_size = 20971520
innodb_buffer_pool_size = 536870912
innodb_file_per_table
innodb_log_buffer_size = 8388608
join_buffer_size = 67104768
max_allowed_packet = 5241856
max_binlog_size = 1073741824
max_heap_table_size = 41943040
query_cache_limit = 10485760
query_cache_size = 157286400
read_buffer_size = 20967424
sort_buffer_size = 67108856
table_cache = 256
thread_cache_size = 128
thread_stack = 327680
tmp_table_size = 41943040

С этими настройками у меня сейчас около 25 минут. Все еще далеко от тех нескольких минут, которые занимает MyISAM, но он становится все более удобным для меня.

Ответы [ 4 ]

126 голосов
/ 30 января 2010

Вы пробовали Советы по массовой загрузке данных из Советов по настройке производительности InnoDB (особенно первого):

  • При импорте данных в InnoDB, убедитесь, что MySQL не имеет режим автоматической фиксации включен, потому что требует сброса журнала на диск для каждого вставить. Отключить автокоммит во время Ваша операция импорта, окружите ее с SET autocommit и COMMIT заявления:

    SET autocommit=0;
    ... SQL import statements ...
    COMMIT;
    

    Если вы используете опцию mysqldump --opt, вы получите файлы дампа, которые быстро импортировать в таблицу InnoDB, даже не оборачивая их SET autocommit и COMMIT заявления.

  • Если у вас есть ограничения UNIQUE для вторичных ключей, вы можете ускорить таблицу импорт путем временного отключения проверка уникальности при импорте сессия:

    SET unique_checks=0;
    ... SQL import statements ...
    SET unique_checks=1;
    

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

  • Если в ваших таблицах есть ограничения FOREIGN KEY, вы можете ускорить импорт таблиц, повернув внешний ключ проверяет для продолжительность сеанса импорта:

    SET foreign_key_checks=0;
    ... SQL import statements ...
    SET foreign_key_checks=1;
    

    Для больших таблиц это может сэкономить много дискового ввода-вывода.

ИМО, вся глава достойна прочтения.

5 голосов
/ 30 января 2010

Вы пытались начать транзакцию с самого начала и завершить ее в конце? Из вопроса , который вы связали : «Измените шаг« Вставка данных », чтобы начать транзакцию в начале и зафиксировать ее в конце. Вы получите улучшение, я гарантирую это».

Помните, что InnoDB является транзакционным, MyISAM - нет. Механизмы транзакций обрабатывают каждый оператор как отдельную транзакцию, если вы явно не контролируете транзакцию. Это может быть дорого.

2 голосов
/ 15 января 2015

Я нашел жесткий диск узким местом - старомодные диски безнадежны, SSD в порядке, но все еще далеки от совершенства. Импорт в tmpfs и копирование данных выполняется намного быстрее, подробности: https://dba.stackexchange.com/a/89367/56667

1 голос
/ 31 мая 2012

У меня были проблемы с большим объемом импорта, и я рекомендовал принятый ответ. Я обнаружил, что вы также можете значительно ускорить процесс:

  1. Удаление всех индексов (кроме первичного ключа), загрузка данных с последующим повторным добавлением индексов
  2. Проверка вашего innodb_log_file_size * innodb_log_files_in_group достаточна, чтобы избежать записи на диск с частотой менее одной секунды

Что касается # 2, по умолчанию 5M * 2 будет недостаточно в современной системе. Подробнее см. innodb_log_file_size и innodb_log_files_in_group

...