Как улучшить производительность MySQL INSERT и UPDATE?

14

Этот вопрос, вероятно, можно задать и в StackOverflow, но сначала я попробую здесь ...

Производительность операторов INSERT и UPDATE в нашей базе данных, похоже, снижает производительность и приводит к снижению производительности нашего веб-приложения.

Таблицы InnoDB и приложение использует транзакции. Есть ли какие-то легкие настройки, которые я могу сделать, чтобы ускорить процесс?

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

mmattax
источник
Лучше на dba.stackexchange.com
Pacerier

Ответы:

25
  1. Проверьте, правильно ли настроено и настроено ваше оборудование и ОС:

    • Источник проблемы (CPU / IO / Memory / Swap Usage). У тебя много IOP? Загружен ли процессор? Если у вас много прочитанных IOP, возможно, вам не хватает большого InnoDB buffer_pool. Если процессор загружен, вероятно, ваши запросы выполняют полное сканирование таблицы, а не используют правильные индексы.
    • Настройка диска / RAID / LVM. В некоторых специфических настройках чередование LVM может дать вам преимущество, уравняв загрузку диска (без аппаратного RAID, подключено несколько LUNS)
    • Планировщик ввода-вывода: когда у вас хороший аппаратный RAID-контроллер, вероятно, лучше всего использовать noop. RedHat провел несколько тестов, и они сказали, что для Oracle (и других БД) CFQ - лучший выбор. Вам нужно запустить несколько тестов (например, tpc-c или tpc-e) и выбрать, что лучше для вашего оборудования.
    • Хорошая файловая система - ext3 плохо работает в определенных рабочих нагрузках базы данных. Лучше XFS или OCFS2. Вам снова нужны некоторые тесты.
    • Смотрите, если ваша система использует своп. Использование свопа снижает производительность MySQL .
  2. Проверьте, правильно ли настроен ваш экземпляр MySQL / InnoDB:

    • размер пула буферов - страницы данных кэша в памяти
    • innodb_flush_method = O_DIRECT - избежать двойной буферизации ввода-вывода
    • увеличьте размер файла журнала InnoDB - для интенсивной записи это может повысить производительность. Но помните: больший размер файла журнала означает более длительное восстановление после сбоя. Иногда в часах !!!
    • innodb_flush_log_at_trx_commit = 0 или 2 - если вы не беспокоитесь о ACID и можете потерять транзакции в течение последней секунды или двух.
    • key_buffer_size - очень важно для MyISAM, но используется для временных таблиц на диске.
    • Следите за своим INNODB STATUS
  3. Проанализируйте свою рабочую нагрузку - перехватите все ваши запросы в журнале медленных запросов и запустите на нем mk-query-digest. Вы можете перехватить все запросы, используя tcpdump и maatkit.
    • Какие запросы занимают большую часть вашего серверного времени?
    • Созданы ли временные таблицы, особенно большие временные таблицы?
    • Узнайте, как использовать объяснить
    • Ваше приложение использует транзакции? Когда вы выполняете запросы с autocommit = 1 (по умолчанию для MySQL), каждый запрос вставки / обновления начинает новую транзакцию, что приводит к некоторым накладным расходам. Если это возможно, лучше отключить автокоммит (в python MySQL драйвер автокоммит отключен по умолчанию) и вручную выполнить коммит после всех модификаций.
    • Ваше приложение делает серию вставок в одну и ту же таблицу в цикле? Load data infileКоманда намного быстрее для серии вставок.
    • Помните: select count(*) from table;гораздо медленнее для innodb, чем для myisam.
    • Какие типы запросов INSERT / UPDATE занимают большую часть времени сервера? Как их можно оптимизировать?
    • Проверьте, есть ли в вашей БД правильные индексы, и добавьте их, если необходимо.

В нашей среде у нас была ситуация, когда один тип запросов на обновление был медленным. Предполагаемое время для завершения пакетной работы было 2 дня !!! Проанализировав журнал медленных запросов, мы обнаруживаем, что для выполнения этого типа запроса на обновление требуется 4 секунды. Запрос выглядит следующим образом : update table1 set field1=value1 where table1.field2=xx table2.field3=yy and table2.field4=zz. После преобразования запроса на обновление для выбора запроса и выполнения объяснения для этого запроса на выборку мы находим, что этот тип запроса не использует индекс. После создания правильного индекса мы сократили время выполнения запроса на обновление до миллисекунд, и вся работа была завершена менее чем за два часа.

Несколько полезных ссылок:

Сумар
источник
Прежде чем все это проверить показатели. Унижающие запахи, такие как «по мере увеличения таблиц, потому что у нас нет индексов».
TomTom
5

С конфигурацией innoDB по умолчанию вы будете ограничены скоростью, с которой вы можете записывать и сбрасывать транзакции на диск. Если вы можете справиться с потерей небольшого количества ACID, поэкспериментируйте с innodb_flush_log_at_trx_commit. Установите 0, чтобы записывать и сбрасывать журнал на диск примерно каждую секунду. Установите 1 (по умолчанию), чтобы записывать и очищать каждый коммит. Установите значение 2 для записи в файл журнала после каждой фиксации, но сбрасывайте только один раз в секунду.

Если вы можете справиться с потерей 1-й транзакции, это может стать отличным способом значительно повысить производительность записи.

Также обратите внимание на то, что делают ваши диски. RAID 10> RAID 5 для записи за счет дополнительного диска.

Томчук
источник
1

Проблемы блокировки будут рассмотрены состояниями соединения в show full processlist;

Прочитайте my.cnfи MySQL документацию. Параметры конфигурации очень хорошо задокументированы.

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

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

сигнализатор
источник
0

InnoDB - довольно хороший движок. Тем не менее, он очень полагается на «настроение». Во-первых, если ваши вставки не в порядке увеличения первичных ключей, innoDB может занять немного больше времени, чем MyISAM. Это можно легко преодолеть, установив более высокое значение innodb_buffer_pool_size. Я предлагаю установить его на 60-70% от общего объема оперативной памяти. Сейчас я работаю на 4 таких серверах, вставляя около 3,5 миллионов строк в минуту. У них уже есть около 3 терабайт. InnoDB это должно было быть, из-за очень параллельных вставок. Есть и другие способы ускорить вставки. И я сравнил некоторые из них.

Аджай Дивакаран
источник
0

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

MySQL Docs

Jatinder
источник