InnoDB против MyISAM время запроса вставки - PullRequest
9 голосов
/ 28 августа 2011

У меня есть большая таблица MySQL (~ 10 миллионов строк, 6,5 ГБ), которую я использую для чтения и записи. Это MyISAM, и я получаю много блокировок из-за блокировки всех таблиц MyISAM при записи.

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

После преобразования я протестировал операторы вставки, и оказалось, что в таблице InnoDB это занимает ~ 15 раз (от 0,1 с до 1,5 с), чем в таблице MyISAM. Почему это так?

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

Дополнительная информация по заявкам:

2 индекса. Первичным является data_id типа Big INT и неуникальный user_id типа varchar (255).

Вставки состоят из ~ 150 строк, имеющих одинаковый идентификатор пользователя.

Размер индексов: 200 МБ в MyISAM, 400 МБ в InnoDB

Ответы [ 4 ]

5 голосов
/ 28 августа 2011

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

4 голосов
/ 28 августа 2011

Я думаю, InnoDB реализует настоящий ACID и делает много fsync() с, чтобы сохранить данные. И MyISAM не является истинной ACID и делает меньше fsync () s.

Есть рекомендации по уничтожению fsync , когда вам нужно загрузить огромные данные в

If you want to load data into InnoDB quickly:
* use as large an InnoDB buffer cache as possible
* make the InnoDB log files as large as possible
* minimize the number of unique indexes on your tables
* disable all calls to fsync from InnoDB. You have to hack the code to
get this, or look at the Google patch. Of course, you only want to run
in this mode when loading the table.

И в списках написано :

MyISAM всегда работает в режиме 'nosync', то есть он никогда не вызывает fsync () для сброса файлов в диск.

InnoDB nosync полезен при тестировании, если какая-то ОС / компьютер работает очень медленно в fsync (). Но его не следует использовать в производственной системе.

В том же сообщении говорится, что InnoDB иногда использует другой метод синхронизации:

Затем InnoDB использует fsync () для очистки как данных, так и файлов журналов. Если O_DSYNC указан, InnoDB использует O_SYNC, чтобы открыть и очистить файлы журнала, но использует fsync () для очистки файлов данных. Если указано O_DIRECT (доступно для некоторых Версии Linux, начиная с MySQL-4.0.14), InnoDB использует O_DIRECT для открытия файлы данных и использует fsync () для очистки как данных, так и файлов журналов. Обратите внимание, что InnoDB не использует fdatasync () или O_DSYNC, потому что были проблемы с ними на многих вкусах Unix.

3 голосов
/ 28 августа 2011

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

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

2 голосов
/ 28 августа 2011

Во-первых, ваш тест недействителен , поскольку увеличение скорости блокировки на уровне строки по сравнению с блокировкой на уровне таблицы происходит при наличии параллелизма! Если в одной вставке используется только одна нить, то в обоих случаях для каждой вставки предусмотрена одна блокировка / разблокировка, и вставки не ожидают снятия блокировки на уровне таблицы.

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

В-третьих, размер пула буферов является одним из наиболее важных параметров в InnoDB. Сделайте его как можно меньше (рекомендуемое значение 80% от доступной оперативной памяти).

Далее, как утверждает @wallyk, innodb_flush_log_at_trx_commit играют решающую роль в скорости операций ввода-вывода.

Далее важны innodb_log_file_size и innodb_buffer_file_size.

Далее, имейте в виду, что, поскольку у вас есть 2 уникальных индекса, прежде чем InnoDB сможет вставить строку, он должен проверить наличие значения в индексах, и ваши индексы велики.

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

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

...