Форум русскоязычного сообщества Ubuntu


Увидели сообщение с непонятной ссылкой, спам, непристойность или оскорбление?
Воспользуйтесь ссылкой «Сообщить модератору» рядом с сообщением!

Автор Тема: Как ускорить запись в MySQL?  (Прочитано 2590 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн thunderamur

  • Автор темы
  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 6846
    • Просмотр профиля
Как ускорить запись в MySQL?
« : 13 Апреля 2016, 11:14:36 »
Каждую секунду пишется 3300 строк, одновременно идут множественные запросы на чтение до 200 строк. Читаются быстро и без проблем, проблема при записи, на дохлом процессоре Pentium 4 время записи достигает 500 мс. Движок БД - InnoDB.
Можно ли как-то в разы ускорить запись? Мб другой движок БД или вообще другую СУБД использовать?
Или скорость записи от python зависит, хотя в этом я сомневаюсь, потому как тот же python по ODBC получает те же данные в 100 раз быстрее. Но возможно дело в executemany, читаются данные то одним запросом, а здесь скорее всего генерируется количество запросов по числу строк...

Код: (python) [Выделить]
    mysql_query = 'INSERT INTO archive2 (chan_id, value) ' \
                  'VALUES (%s, %s)'
    mysql_cursor.execute('TRUNCATE archive2')
    mysql_cursor.executemany(mysql_query, odbc_rows)
    mysql_conn.commit()
« Последнее редактирование: 13 Апреля 2016, 12:14:52 от thunderamur »

Axa-Ru

  • Гость
Re: Как ускорить запись в MySQL?
« Ответ #1 : 13 Апреля 2016, 13:27:40 »
Попробуй оптимизировать настройки MySQL: буферы и кэши.
Если это уже сделано, то - плохие новости.
Если 3300 строк - это средняя нагрузка в течение продолжительного времени, скорее всего, программно никак.

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

Нашим программистам удалось таким способом поднять производительность в несколько раз. У нас Postgress, хотя это принципиально дела не меняет.
« Последнее редактирование: 13 Апреля 2016, 13:36:04 от Axa-Ru »

Оффлайн thunderamur

  • Автор темы
  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 6846
    • Просмотр профиля
Re: Как ускорить запись в MySQL?
« Ответ #2 : 13 Апреля 2016, 13:57:30 »
Эта вся канитель из-за того, что ODBC-сервер используемого ПО не переваривает множественные одновременные запросы. Я попробовал решить проблему таким образом, что питон постоянно опрашивает ODBC и пишет данные в MySQL, который уже без напряга отвечает куче клиентов.

Ещё одни вариант - сделать так, чтобы скрипт python, который получает данные по ODBC не писал их в MySQL, а запоминал и отдавал по запросам от PHP, можно ли как-то сделать так, чтобы python прикинулся MySQL, который просто умеет отдавать нужные данные из массива, индексы которых указаны в запросе?

Либо даже без MySQL, как-то можно организовать взаимодействия Python и PHP напрямую? Простой вариант файлы, но это медленно, хотя наверное попробую. Скорее всего можно как-то через сеть обмен организовать.
« Последнее редактирование: 13 Апреля 2016, 13:59:30 от thunderamur »

Axa-Ru

  • Гость
Re: Как ускорить запись в MySQL?
« Ответ #3 : 13 Апреля 2016, 14:02:37 »
Мне кажется последний вариант плохой. Высока опасность получить неконсистентную базу.
Хотя это все зависит от конкретного приложения.

Посмотри на Redis. Может это то, что тебе нужно.
С питоном там есть модуль готовый.
« Последнее редактирование: 13 Апреля 2016, 14:05:38 от Axa-Ru »

Оффлайн thunderamur

  • Автор темы
  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 6846
    • Просмотр профиля
Re: Как ускорить запись в MySQL?
« Ответ #4 : 13 Апреля 2016, 14:06:20 »
Axa-Ru, напиши подробнее в чем может быть подвох?

Axa-Ru

  • Гость
Re: Как ускорить запись в MySQL?
« Ответ #5 : 13 Апреля 2016, 14:09:37 »
Если ты собираешь асинхронно в памяти и в базе, то в какие то моменты времени у тебя система встает на синхронизацию всего этого барахла, либо, если ты не используешь локи, получается неконсистентная база.
Например из памяти ты запись выкинул а из базы еще нет.
В общем это такая не простая тема.
Нужно тщательно архитектуру проектировать.

Оффлайн thunderamur

  • Автор темы
  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 6846
    • Просмотр профиля
Re: Как ускорить запись в MySQL?
« Ответ #6 : 13 Апреля 2016, 14:16:10 »
Axa-Ru, я читаю данные из ODBC, и отдаю их по запросам клиентов до следующего чтения, после чего данные обновляются и по новой.
А я понял, ты говоришь о том, что запрос данных из массива в питоне могут совпасть по времени с изменением данных в этом самом массиве? Значит надо запросы ставить в очередь, пока данные не будет готовить, как-то так наверное.

Пользователь добавил сообщение 13 Апреля 2016, 14:17:17:
Axa-Ru, да Redis мб то, что нужно, спасибо, почитаю, попробую.

Оффлайн it0r

  • Забанен
  • Старожил
  • *
  • Сообщений: 2264
    • Просмотр профиля
Re: Как ускорить запись в MySQL?
« Ответ #7 : 13 Апреля 2016, 14:56:39 »
thunderamur, залокировал значит... :coolsmiley:
ТУТ - это дерево. А ЗДЕСЬ - это МЕСТО.... Так что ТУТ - это не ЗДЕСЬ.

Оффлайн thunderamur

  • Автор темы
  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 6846
    • Просмотр профиля
Re: Как ускорить запись в MySQL?
« Ответ #8 : 13 Апреля 2016, 15:31:22 »
it0r, чего залокировал?

Оффлайн victor00000

  • Старожил
  • *
  • Сообщений: 15568
  • Глухонемой (Deaf)
    • Просмотр профиля
Re: Как ускорить запись в MySQL?
« Ответ #9 : 13 Апреля 2016, 15:43:05 »
не умею, как mysql_open и mysql_close.

Wars ~.o

Оффлайн Azure

  • Модератор раздела
  • Старожил
  • *
  • Сообщений: 6017
  • Windows10, i3wm on Debian9, Manjaro20.0
    • Просмотр профиля
Re: Как ускорить запись в MySQL?
« Ответ #10 : 13 Апреля 2016, 16:20:24 »
И может пригодится: быстрее всего python работает с словарями: чтоб не по индексу отдавать, а по ключу.
В Линукс можно сделать ВСЁ что угодно, достаточно знать КАК !

Оффлайн MooSE

  • Старожил
  • *
  • Сообщений: 1116
    • Просмотр профиля
Re: Как ускорить запись в MySQL?
« Ответ #11 : 13 Апреля 2016, 16:41:55 »
Если есть возможность то надо писать не по одной строке, а потом. Для этого берёшь любой менеджер очередей (например rabbitmq) и пишешь данные в него. Раз в минуту вычитываешь данные из очереди, формируешь запрос на вставку сразу всех данных и выполняешь его.

При вставке данных основное время занимает не запись данных, а перестроение индексов. Вставляешь N строк за N транзакций - индексы перестраиваются N раз. Вставляешь N-строк одной транзакцией - индексы перестраиваются один раз.

Оффлайн thunderamur

  • Автор темы
  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 6846
    • Просмотр профиля
Re: Как ускорить запись в MySQL?
« Ответ #12 : 13 Апреля 2016, 17:04:25 »
MooSE, мне нужно писать данные в таблицу каждую секунду, потому что клиенты должны получать свежие данные с небольшой задержкой. Если ты посмотришь внимательно то увидишь, что я даже таблицу каждую секунду очищаю, т.е. нет никакого смысла в накоплении очереди.
executemany() пишет данные кучей запросов, а не одним? Тоже про это думал, возможно это так, тогда тормознутость этим и объясняется. Мб попробовать сформировать один мегазапрос и попробовать скормить его за один execute()?

Оффлайн MooSE

  • Старожил
  • *
  • Сообщений: 1116
    • Просмотр профиля
Re: Как ускорить запись в MySQL?
« Ответ #13 : 13 Апреля 2016, 17:19:38 »
MooSE, мне нужно писать данные в таблицу каждую секунду, потому что клиенты должны получать свежие данные с небольшой задержкой. Если ты посмотришь внимательно то увидишь, что я даже таблицу каждую секунду очищаю, т.е. нет никакого смысла в накоплении очереди.
executemany() пишет данные кучей запросов, а не одним? Тоже про это думал, возможно это так, тогда тормознутость этим и объясняется. Мб попробовать сформировать один мегазапрос и попробовать скормить его за один execute()?

Тогда может вообще не InnoDB, а memory?

Оффлайн thunderamur

  • Автор темы
  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 6846
    • Просмотр профиля
Re: Как ускорить запись в MySQL?
« Ответ #14 : 13 Апреля 2016, 18:35:23 »
MooSE, я планировал другие движки, но даже не смотрел, что можно использовать. Сейчас посмотрел, MEMORY - то, что нужно. Думаю с ним будет намного бодрее. Спасибо.

 

Страница сгенерирована за 0.056 секунд. Запросов: 25.