Как в базу данных MySQL выгружать по 10 000 строк в минуту?

Gunjubasik

Client
Регистрация
30.05.2019
Сообщения
3 521
Благодарностей
1 318
Баллы
113
Доброго времени. Столкнулся с такой проблемой, что сохраняя в многопотоке, допустим в 100 потоков - каждую секунду по 100+ строк - не выходит сохранить в базу более 150-200 записей в минуту. Та даже и в блокнот не выходит так быстро сохранять строки, где символов примерно по 250-500 максимум. То ли в зенке ограничения каике-то стоят, то ли сам лок срабатывает и из-за очереди такая маленькая скорость выходит - не могу никак понять. Может есть у кого какие идеи или это только у меня такие проблемы, а у остальных по 100 000 строк в минуту загружает и в базу и в блокнот в 100+ потоков?
 

WebBot

Client
Регистрация
04.04.2015
Сообщения
1 763
Благодарностей
1 391
Баллы
113
Тут много вопросов. Какой движок innodb или myisam (последний на вставку записей скорее всего будет быстрее хоть и считается уже как бы устаревшим по сравнению с innodb) ? есть ли у таблицы индексы ( при записи каждый раз перестраивается индекс ) ? используется ли пакетное добавление или каждое добавление отдельный запрос? бд живет на ssd ? пробовали ли сначала данные собирать в памяти (это несравнимо по скорости с файловой системой), а потом разом копировать когда накопилось?
 
Последнее редактирование:

Gunjubasik

Client
Регистрация
30.05.2019
Сообщения
3 521
Благодарностей
1 318
Баллы
113
Какой движок innodb или myisam
Эта база - от хостинга. Детальнее не знаю как узнать.
есть ли у таблицы индексы
96963
используется ли пакетное добавление или каждое добавление отдельный запрос
Примерно так без учета Lock (Пробовал и с ним и без него - скорость не меняется):
96962
На хостинге - думаю cloud + ssd на нем по идее.
пробовали ли сначала данные собирать в памяти (это несравнимо по скорости с файловой системой), а потом разом копировать когда накопилось?
Нет, так как не понимаю как это делается вообще. Можно пожалуйста пример?


И повторюсь, даже в блокнот в многопотоке не выходит таким методом через C#+парсинг+добавление в блокнот - записывать больше чем 200 строк в минуту. Возможно и на блокноте стоит лок, который не позволяет параллельно быстро записывать в блокнот данные?
 

Shogo

Client
Регистрация
07.04.2015
Сообщения
474
Благодарностей
100
Баллы
43

tanichev

Client
Регистрация
14.08.2020
Сообщения
654
Благодарностей
761
Баллы
93
Эта база - от хостинга. Детальнее не знаю как узнать.


Примерно так без учета Lock (Пробовал и с ним и без него - скорость не меняется):

На хостинге - думаю cloud + ssd на нем по идее.

Нет, так как не понимаю как это делается вообще. Можно пожалуйста пример?


И повторюсь, даже в блокнот в многопотоке не выходит таким методом через C#+парсинг+добавление в блокнот - записывать больше чем 200 строк в минуту. Возможно и на блокноте стоит лок, который не позволяет параллельно быстро записывать в блокнот данные?
1. это можно посмотреть в конфиге муськи
2. можно создавать индекс например на 2 столбца, например primary индекс + простой по другому столбцу
3. Пакетное человек имеет введу, что ты перегружаешь базу единичными запросами, работай пачками
4. поковыряй конфиг муськи и она норм заработает
 

tanichev

Client
Регистрация
14.08.2020
Сообщения
654
Благодарностей
761
Баллы
93

Gunjubasik

Client
Регистрация
30.05.2019
Сообщения
3 521
Благодарностей
1 318
Баллы
113
10 тысяч строк должно не за минуту, а несколько миллисекунд
1. это можно посмотреть в конфиге муськи
2. можно создавать индекс например на 2 столбца, например primary индекс + простой по другому столбцу
3. Пакетное человек имеет введу, что ты перегружаешь базу единичными запросами, работай пачками
4. поковыряй конфиг муськи и она норм заработает
Уровень помощи ровно такой, как и в вашем платном курсе.
 
  • Спасибо
Реакции: djaga

WebBot

Client
Регистрация
04.04.2015
Сообщения
1 763
Благодарностей
1 391
Баллы
113
дак может дело не скорости записи, а в том что сам парсинг не слишком быстр?

про память я имел ввиду таблицы типа MEMORY ... такая таблица целиком хранится в RAM и соответственно скорость чтения/записи из нее просто космическая по срвнению с hdd ... то есть можно писать в нее и например раз в минуту скидывать в обычную таблицу все что накопилось

ну и конечно нужно объединять все эти одиночные инсерты из цикла в один запрос (пакет)
 

Gunjubasik

Client
Регистрация
30.05.2019
Сообщения
3 521
Благодарностей
1 318
Баллы
113
дак может дело не скорости записи, а в том что сам парсинг не слишком быстр?
Для этого и запускаю 100 потоков, что бы открылось 100 страниц и каждый поток парсит свои данные. Каждый поток спаршивает 1ну строку данных за 1-3 секунды в среднем. Соответственно, было предположение, что 100 потоков, запишут за 1-3 секунды - 100 ссылок примерно. Но на сколько я понял, есть какое-то либо ограничение, либо что-то еще, что мешает построить подобную логику.
 

WebBot

Client
Регистрация
04.04.2015
Сообщения
1 763
Благодарностей
1 391
Баллы
113
Скорее всего проблема не в скорости записи, а в том что по факту при 100 потоках по каким-то причинам это занимает не 1-3 сек
Для БД записать 100 строк за несколько сек это вообще не проблема.
Вот вы привели там небольшой кусок кода выше ... там цикл от 1 до Count а в нем парсинг идет и запись ... его вы в 100 потоков пускаете? тогда все же получается что каждый поток спаршивает не 1 строку и делает не 1 запись в БД, а Count раз.... вот если бы там после записи в БД стоял break;, то была бы 1 строка и 1 запись, а так цикл продолжается ... может все-таки есть какая-то проблема в логике?
 

Gunjubasik

Client
Регистрация
30.05.2019
Сообщения
3 521
Благодарностей
1 318
Баллы
113
Скорее всего проблема не в скорости записи, а в том что по факту при 100 потоках по каким-то причинам это занимает не 1-3 сек
Для БД записать 100 строк за несколько сек это вообще не проблема.
Вот вы привели там небольшой кусок кода выше ... там цикл от 1 до Count а в нем парсинг идет и запись ... его вы в 100 потоков пускаете? тогда все же получается что каждый поток спаршивает не 1 строку и делает не 1 запись в БД, а Count раз.... вот если бы там после записи в БД стоял break;, то была бы 1 строка и 1 запись, а так цикл продолжается ... может все-таки есть какая-то проблема в логике?
Не совсем понимаю, а что не так то?
1. Открываю коннект в БД
2. Паршу Данные-1
3. Записываю в БД
4. Паршу Данные-2
5. Записываю в БД
6. И так пока не соберутся все данные из страницы и не запишутся
7. Закрываем Коннект с БД

Я наоборот думал что так будет оптимальнее по нагрузке на БД, так как не приходится каждый раз открывать\закрывать коннект в БД, тем самым меньше будет нагрузка.
Но повторюсь, такая же ситуация и с записью в блокнот - скорость примерно 200 в минуту в многопотоке. Хоть 1 поток, хоть 100 потоков.
 

marushin

Client
Регистрация
12.01.2015
Сообщения
193
Благодарностей
60
Баллы
28

tanichev

Client
Регистрация
14.08.2020
Сообщения
654
Благодарностей
761
Баллы
93
Не совсем понимаю, а что не так то?
1. Открываю коннект в БД
2. Паршу Данные-1
3. Записываю в БД
4. Паршу Данные-2
5. Записываю в БД
6. И так пока не соберутся все данные из страницы и не запишутся
7. Закрываем Коннект с БД

Я наоборот думал что так будет оптимальнее по нагрузке на БД, так как не приходится каждый раз открывать\закрывать коннект в БД, тем самым меньше будет нагрузка.
Но повторюсь, такая же ситуация и с записью в блокнот - скорость примерно 200 в минуту в многопотоке. Хоть 1 поток, хоть 100 потоков.
я бы рекомендовал под твою задачу накатить postgresql и использовать jsonb. Именно под вашу задачу
 

BAZAg

Client
Регистрация
08.11.2015
Сообщения
1 787
Благодарностей
2 453
Баллы
113
Gunjubasik сказал(а):
Как в базу данных MySQL выгружать по 10 000 строк в минуту?
Отправляйте 10 запросов по 1000 строк каждых 6 секунд, вместо того, чтобы задалбивать базу запросами.

Не совсем понимаю, а что не так то?
1. Открываю коннект в БД
2. Паршу Данные-1
3. Записываю в БД
4. Паршу Данные-2
5. Записываю в БД
6. И так пока не соберутся все данные из страницы и не запишутся
7. Закрываем Коннект с БД

Я наоборот думал что так будет оптимальнее по нагрузке на БД, так как не приходится каждый раз открывать\закрывать коннект в БД, тем самым меньше будет нагрузка.
Но повторюсь, такая же ситуация и с записью в блокнот - скорость примерно 200 в минуту в многопотоке. Хоть 1 поток, хоть 100 потоков.
Это и касается файлов - пишите в файл данные пачками, чтобы минимизировать накладные расходы на открытие/закрытие файлов.
А то получается, что 90% времени тратится только на то чтобы открыть/закрыть файл, а не на целевую операцию добавления туда данных.
 
  • Спасибо
Реакции: Gunjubasik

WebBot

Client
Регистрация
04.04.2015
Сообщения
1 763
Благодарностей
1 391
Баллы
113
Не совсем понимаю, а что не так то?
Если так задумано, то все так. Просто выше вы писали "Каждый поток спаршивает 1ну строку данных за 1-3 секунды в среднем. "
Поэтому я подумал что каждый поток должен парсить строго 1ну ссылку и делать 1 запись, но когда увидел цикл подумал что это нарушение этой логики.

Никаких локов в БД не ставится? или локов самим ZP ? они там не нужны!

Но повторюсь, такая же ситуация и с записью в блокнот - скорость примерно 200 в минуту в многопотоке. Хоть 1 поток, хоть 100 потоков.
200 в минуту да же в 1 поток .... уж очень похоже на то что да же при выставленных 100 потоках по факту работает 1 поток, а остальные ждут ... локи нужно смотреть
 
Последнее редактирование:

WebBot

Client
Регистрация
04.04.2015
Сообщения
1 763
Благодарностей
1 391
Баллы
113

backoff

Client
Регистрация
20.04.2015
Сообщения
6 052
Благодарностей
6 481
Баллы
113
Не совсем понимаю, а что не так то?
1. Открываю коннект в БД
2. Паршу Данные-1
3. Записываю в БД
4. Паршу Данные-2
5. Записываю в БД
6. И так пока не соберутся все данные из страницы и не запишутся
7. Закрываем Коннект с БД
1. парси сначала все данные и отправляй их одним запросом.
2. на запись в БД локи не нужны
3. открывать закрывать коннект тоже не нужно
 
  • Спасибо
Реакции: BAZAg

Wide

Client
Регистрация
04.02.2013
Сообщения
945
Благодарностей
257
Баллы
63
3. Пакетное человек имеет введу, что ты перегружаешь базу единичными запросами, работай пачками
Добавляем в список запросы
('0','{-Variable.product_id-}','{-Variable.md5-}','{-Variable.base64-}','{-Variable.type-}')
('0','{-Variable.product_id-}','{-Variable.md5-}','{-Variable.base64-}','{-Variable.type-}')
('0','{-Variable.product_id-}','{-Variable.md5-}','{-Variable.base64-}','{-Variable.type-}')
Количество строк отправляемых за один запрос зависит от конфига, можешь для уверенности брать по 1000 строк.

Объединяем список в {-Variable.insert-} с разделителем запятой

Screenshot_305.png


Выполняем запрос
INSERT INTO `images`(`id`, `product_id`, `md5`, `base64`, `type`) VALUES ({-Variable.insert-})
 
Последнее редактирование:

Wide

Client
Регистрация
04.02.2013
Сообщения
945
Благодарностей
257
Баллы
63

WebBot

Client
Регистрация
04.04.2015
Сообщения
1 763
Благодарностей
1 391
Баллы
113
Первичный ключ с автоинкрементом у него есть (во всяком случае по тому скриншоту структуры что был выложен под спойлером).
Все остальные индексы создаваемые в этой таблице будут только все затормаживать т.к при каждой вставке новых данных будет и перестройка индекса производиться. Так что наоборот на таблицу в которую идет очень активная запись нужно убрать все индексы (кроме критически важных)
 

Wide

Client
Регистрация
04.02.2013
Сообщения
945
Благодарностей
257
Баллы
63
Первичный ключ с автоинкрементом у него есть (во всяком случае по тому скриншоту структуры что был выложен под спойлером).
Все остальные индексы создаваемые в этой таблице будут только все затормаживать т.к при каждой вставке новых данных будет и перестройка индекса производиться. Так что наоборот на таблицу в которую идет очень активная запись нужно убрать все индексы (кроме критически важных)
не увидел)
 

tanichev

Client
Регистрация
14.08.2020
Сообщения
654
Благодарностей
761
Баллы
93
Первичный ключ с автоинкрементом у него есть (во всяком случае по тому скриншоту структуры что был выложен под спойлером).
Все остальные индексы создаваемые в этой таблице будут только все затормаживать т.к при каждой вставке новых данных будет и перестройка индекса производиться. Так что наоборот на таблицу в которую идет очень активная запись нужно убрать все индексы (кроме критически важных)
ему FULLTEXT может подойти, я так понял он хочет же парсить и записывать текст
 

Wide

Client
Регистрация
04.02.2013
Сообщения
945
Благодарностей
257
Баллы
63
ему FULLTEXT может подойти, я так понял он хочет же парсить и записывать текст
Причем здесь тип данных до индекса?) Конкретно по индексу или примари или кей ему нужен.
 

WebBot

Client
Регистрация
04.04.2015
Сообщения
1 763
Благодарностей
1 391
Баллы
113
ему FULLTEXT может подойти, я так понял он хочет же парсить и записывать текст
любой индекс нужен исключительно для ускорения чтения данных из таблиц и любой индекс всегда затормаживает вставку данных (так как будет перестройка индекса при каждый вставке)... поэтому нужно определить в рамках конкретного проекта что важнее и какие операции с таблицей (чтение или запись) производятся чаще ... а просто так лепить индекс абы был не имеет никакого смысла
 
  • Спасибо
Реакции: Wide

tanichev

Client
Регистрация
14.08.2020
Сообщения
654
Благодарностей
761
Баллы
93
  • Спасибо
Реакции: Wide

Wide

Client
Регистрация
04.02.2013
Сообщения
945
Благодарностей
257
Баллы
63

Gunjubasik

Client
Регистрация
30.05.2019
Сообщения
3 521
Благодарностей
1 318
Баллы
113
Всем спасибо, увеличил скорость вроде как.
 
Последнее редактирование:

Gunjubasik

Client
Регистрация
30.05.2019
Сообщения
3 521
Благодарностей
1 318
Баллы
113
2. на запись в БД локи не нужны
3. открывать закрывать коннект тоже не нужно
Были случаи, когда коннекты были в режиме Sleep и не закрывали, что создавало большую нагрузку на базу данных, пришлось доделывать db.close
 
  • Спасибо
Реакции: Андрейка2020
Регистрация
26.05.2020
Сообщения
495
Благодарностей
172
Баллы
43
Были случаи, когда коннекты были в режиме Sleep и не закрывали, что создавало большую нагрузку на базу данных, пришлось доделывать db.close
в конце отработки потока и по BAD END?
Можно подробнее?
 

Кто просматривает тему: (Всего: 1, Пользователи: 0, Гости: 1)