Я работаю над приложением, которое включает в себя много записей в базе данных, примерно ~ 70% операций вставки и 30% операций чтения. Это соотношение также включает в себя обновления, которые я считаю одним чтением и одной записью. Через операторы вставки несколько клиентов вставляют данные в базу данных через оператор вставки ниже:
$mysqli->prepare("INSERT INTO `track` (user, uniq_name, ad_name, ad_delay_time ) values (?, ?, ?, ?)");
Вопрос в том, должен ли я использовать либо insert_delay, либо механизм mysqli_multi_query , потому что оператор вставки использует ~ 100% ЦП на сервере. Я использую движок InnoDB в своей базе данных, поэтому вставка с задержкой невозможна. Вставка на сервер ~ 36k / ч и чтение 99,89%, также я использую оператор SELECT, чтобы получить данные семь раз в одном запросе , этот запрос занимает 150 секунд на сервере для выполнения. Какую технику или механизм я могу использовать для этой задачи? Моя память сервера составляет 2 ГБ, я должен расширить память ?. Посмотрите на эту проблему, любые предложения будут благодарны мне.
Структура стола:
+-----------------+--------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+--------------+------+-----+-------------------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| user | varchar(100) | NO | | NULL | |
| uniq_name | varchar(200) | NO | | NULL | |
| ad_name | varchar(200) | NO | | NULL | |
| ad_delay_time | int(11) | NO | | NULL | |
| track_time | timestamp | NO | MUL | CURRENT_TIMESTAMP | |
+-----------------+--------------+------+-----+-------------------+----------------+
Состояние моей базы данных в настоящий момент показывает 41 тыс. Вставок (записей), что очень медленно для моей базы данных.
SHOW FULL PROCESSLIST
когда он берет 100% процессора? Сколько соединений вы разрешаете против того, сколько было взято за это время?SHOW GLOBAL VARIABLES LIKE 'innodb%';
иSELECT VERSION();
и отобразите их вывод.Ответы:
Поскольку у вас есть больше записей, чем читает, я хотел бы рекомендовать следующее
Достойная настройка InnoDB будет ключевым
Буферный пул (размер innodb_buffer_pool_size )
Поскольку InnoDB не поддерживает INSERT DELAYED , использование большого пула буферов InnoDB - это самая близкая вещь, которую вы можете получить для INSERT DELAYED. Все DML (INSERT, UPDATE и DELETE) будут кэшироваться в пуле буферов InnoDB. Транзакционная информация для записей немедленно записывается в журналы повторов (ib_logfile0, ib_logfile1). Записи, которые публикуются в пуле буферов, периодически сбрасываются из памяти на диск через ibdata1 (InsertBuffer для вторичных индексов, двойной буфер записи). Чем больше буферный пул, тем большее количество INSERT может быть кэшировано. В системе с 8 ГБ или более ОЗУ используйте 75-80% ОЗУ в качестве innodb_buffer_pool_size. В системе с очень небольшим объемом оперативной памяти - 25% (для размещения ОС).
CAVEAT: Вы можете установить innodb_doublewrite в 0, чтобы ускорить запись еще больше, но с риском целостности данных. Вы также можете ускорить процесс, установив innodb_flush_method в O_DIRECT, чтобы предотвратить кеширование InnoDB в ОС.
Восстановить журналы ( размер innodb_log_file_size )
По умолчанию журналы повторов имеют имена ib_logfile0 и ib_logfile1 и будут по 5 МБ каждый. Размер должен быть 25% от innodb_buffer_pool_size. Если журналы повторов уже существуют, добавьте новый параметр в my.cnf, завершите работу mysql, удалите их и перезапустите mysql .
Буфер журналов ( размер innodb_log_buffer_size )
В буфере журнала хранятся изменения в оперативной памяти перед их сбросом в журналы повторов. По умолчанию это 8M. Чем больше буфер журнала, тем меньше дисковый ввод-вывод. Будьте осторожны с очень большими транзакциями, так как это может замедлить COMMIT на миллисекунды.
Доступ к нескольким процессорам
MySQL 5.5 и плагин MySQL 5.1 InnoDB имеют настройки для доступа InnoDB Storage Engine к нескольким процессорам. Вот параметры, которые вам нужно установить:
Обновление до MySQL 5.5
Если у вас MySQL 5.0, обновитесь до MySQL 5.5. Если у вас MySQL 5.1.37 или более ранней версии, обновитесь до MySQL 5.5. Если у вас MySQL 5.1.38 или выше и вы хотите остаться в MySQL 5.1, установите плагин InnoDB. Таким образом, вы можете воспользоваться всеми процессорами для InnoDB.
источник
INT (2) по-прежнему использует 4 байта - возможно, вы имели в виду TINYINT UNSIGNED?
Сколько разных значений в сетно? Если он маленький, ключ (setno) никогда не будет использоваться. INSERTing должен обновить этот индекс; удаление КЛЮЧА ускорит вставку некоторых.
CHAR (10) - это
flag
всегда 10 символов? А в utf8? Возможно, вы могли бы использовать флаг VARCHAR (10) CHARACTER SET asciiПакетные вставки - 100 за раз будет работать в 10 раз быстрее. (За 100 входит в «убывающую отдачу».)
Какова ценность автокоммитов? Вы упаковываете каждую вставку в BEGIN ... COMMIT? Какое значение имеет innodb_flush_log_at_trx_commit?
источник
code
вставка в значения t_name (col1, col2, col3) (val1, val2, val3), (val1, val2, val3), (val1, val2, val3), (val1, val2, val3), (val1, val2, val3);code
Настройте очередь. Приложение будет записывать в очередь по 1 строке за раз, а затем извлекать строки и вставлять их в базу данных в пакетном режиме на основе количества строк или количества времени, прошедшего с момента последней вставки.
Я видел, что пакетирование 10 000 вставок за раз является самым быстрым, поэтому вам нужно проверить, чтобы найти подходящее место.
Вы можете создать свою собственную простую систему очередей или использовать существующую. Вот несколько примеров: HornetQ и File :: Queue . Вот сообщение о SE, в котором перечислены некоторые другие полезные опции: очереди сообщений в perl, php, python .
источник