LINUX.ORG.RU

Помогите повысить производительность MySQL

 , ,


0

1

Пишу игру суть токова

Нужно много (~120KK записей) сдампить в MySQL, железо - 32ГБ RAM/Core i5 какой-то на 2 ядра + ssd. Кода под рукой нет, описываю суть: в тредпуле открывается 8(или 16) соединений, из файла читается построчно инфа, парсится и суется в БД. Загрузка CPU 25-60%, iostat показывает, что на диск пишется 16MiB/sec, загрузка 80%+. Дело в том, что я нубло еще то, и не понимаю, что тюнить. Нашел что-то здесь (https://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html#sysvar_innodb_...), увеличил размер буфера - не помогло. Прошелся по опциям, запутался, попробовал комбинировать что-то - не помогает, все та же фигня. Сейчас происходит запись в 2 таблицы (в одну - 2К строк, во вторую - 15-20K в секунду, по грубым оценкам). Я так понимаю, мне нужно сделать так, чтобы оно писалось реже, но большими порциями, ибо база расположена на ссд и скорость записи не должна быть ботлнеком. Вопрос в том, почему увеличенный размер buffer pool (еще поднимал к-во самих buffer_pool_instances) не привел к ожидаемому результату.

Что читать, что пробовать, что крутить?

Может, уменьшить кол-во конкурентных тредов? (они читают все из разных файлов (как раз 16 файлов), т.е. по треду на файл, но могу сделать что-то вроде по 1 треду на 2-4 файла, хотя вряд ли в этом дело, да и задержка должна увеличиться)

★★★★★

Последнее исправление: cdshines (всего исправлений: 1)

если пишешь в одну таблицу, то определённо не стоит делать много потоков

Я так понимаю, мне нужно сделать так, чтобы оно писалось реже, но большими порциями

естественно, вставлять по одной записи за транзакцию не стоит.

mashina ★★★★★
()
Ответ на: комментарий от goingUp

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

Что-то я не понял, какое мне подходит значение вышеуказанной опции :/

cdshines ★★★★★
() автор топика
Ответ на: комментарий от mashina

Я имею в виду, сбрасывалось из кэша в диск, потому как я сделал большой кэш в памяти, и туда не жалко вроде писать порциями по 20-25 записей за транзакцию? Или какие мне попробовать числа?

Черт, почему я вечером спрашиваю, когда уже под рукой ничего нет? :(

cdshines ★★★★★
() автор топика
Ответ на: комментарий от cdshines

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

Ну тогда сильно быстро не будет.

Что-то я не понял, какое мне подходит значение вышеуказанной опции :/

0

goingUp ★★★★★
()
Ответ на: комментарий от goingUp

Спасибо.

Я могу, в приципе, как-то аккумулировать серии по 10-20 прочитанных строк (это 200-400 строк в дб). Это будет производительнее?

cdshines ★★★★★
() автор топика
Ответ на: комментарий от cdshines

Не нужно будет 100500 раз в секунду переключать контекст между скриптом и mysql, разбирать sql, проверять блокировки... Ускорение может быть на порядок. А трудность в том, что таблицы связаны и в одну из них нужно вставлять id из auto increment поля другой?

goingUp ★★★★★
()
Ответ на: комментарий от goingUp

нет, там вообще id из файла берутся. Просто в одной строке содержится id + набор других id, связанных с этим определенным образом. Т. е. в одну таблицу я вставляю id + какие-то данные из строки, а в другую - n строк | id | another id_i |, i = 1, ...., n, n в среднем ок. 20.

cdshines ★★★★★
() автор топика
Ответ на: комментарий от cdshines

Если все id известны, почему нельзя аккумулировать эти данные в памяти, и периодически отправлять в mysql?

goingUp ★★★★★
()
Ответ на: комментарий от goingUp

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

cdshines ★★★★★
() автор топика
Ответ на: комментарий от cdshines

innodb_flush_log_at_trx_commit = 1 означает, что, когда mysql возвращает скрипту результат, что запрос прошел успешно, данные уже должны быть сброшены на диск. Ну и обрабатывать каждую вставку по отдельности дольше.

goingUp ★★★★★
()

на сколько я понял прочитав тред ты без всякого вставляешь insert into table (v1, v2, v3)... думаю, что можно попробовать использовать транзакции. в смысле они конечно и так используются, но по одной на запись. а ты сделай BEGIN TRANSACTION (или как оно там), погоди немного (раз в сто больше чем сейчас) и сделай commit. И опять бегин/комит. Желательно чтобы транзакция влазила в буфер. Много потоков не делай коли все равно паралельно вставлять не можешь.

AndreyKl ★★★★★
()

ещё как идея - убери ключи/ограничения, а потом после завершения операции добавь их.

AndreyKl ★★★★★
()

сначалу сконверть все свои файлики в формат sql, отключи все индексы как тут совитовали, потом залей их в базу как mysqldump заливают.

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

anonymous
()
Ответ на: комментарий от anonymous

«залей в базу» не индексы, а файлы сконвертченные. а индексы потом включишь, придётся правда вручную искать и править косяки в данных, которые не дадут индексам включиться, но это дело хать и мутарное но уж точно без тормозов...

anonymous
()
Ответ на: комментарий от nerdogeek

Там нужно некоторые места еще разобрать, а не просто выкинуть в файл как есть, к сожалению.

cdshines ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.