Помогите оптимизировать код (запросы к БД)

Поддержка
  • @doupiu said in Помогите оптимизировать код (запросы к БД):

    @sergerdn хорошо, пусть будет так, я не защищаю mongodb и это не является целью топика) Не могли бы вы подсказать, хотя бы в общих чертах, как данная проблема решается в других БД? Потому что если бы я это делал на другой БД - я бы сделал ту же самую логику и столкнулся бы с той же самой проблемой..

    У многих БД есть тригеры которые срабатывают по определенным условиям. У монго то же есть, но связать это с БАС все равно будет проблематично.

  • @UserTrue said in Помогите оптимизировать код (запросы к БД):

    У многих БД есть тригеры которые срабатывают по определенным условиям. У монго то же есть, но связать это с БАС все равно будет проблематично.

    Человек где-то в соседней теме связывал BAS c https://www.rabbitmq.com/ или подобное. Не знаю насколько успешно или нет.

    Вероятно, это и нужно @doupiu.

  • @sergerdn said in Помогите оптимизировать код (запросы к БД):

    Человек где-то в соседней теме связывал BAS c https://www.rabbitmq.com/ или подобное. Не знаю насколько успешно или нет.

    Вероятно, это и нужно @doupiu.

    Если писать кодом то проблем с любой БД и менеджер очередей тут как по мне оверхэд, но если писать кубиками в БАС это будет проблема )

  • @sergerdn @UserTrue Увы, да, вы правы, но менять БД ради этой проблемы просто нецелесообразно с т.з ресурсов (хоть и возможно), потому что в остальном mongodb работает нормально.

    Но полагаю, что даже средствами BAS можно неидеально (но приемлимо) решить проблему. Поэтому и был создан данный топик, думал пообщаться с теми, кто работает с mongodb BAS-овской.

    Пришла в голову идея, что можно завести отдельный асинхронный поток, который будет дергать БД каждые 100 мс и сохранять результат в глобалку. Итого 1 запрос против 50 при той же частоте проверок. По факту тот же триггер, сделанный вручную. Вот надеялся, что кто-то уже делал что-то подобное и что-то посоветует.

  • @doupiu said in Помогите оптимизировать код (запросы к БД):

    Пришла в голову идея, что можно завести отдельный асинхронный поток, который будет дергать БД каждые 100 мс и сохранять результат в глобалку. Итого 1 запрос против 50 при той же частоте проверок. По факту тот же триггер, сделанный вручную. Вот надеялся, что кто-то уже делал что-то подобное и что-то посоветует.

    Да тогда уж проще реализовать longpolling к источнику данный которые присылает данные в БД, то есть делается запрос без таймаута и висит пока сервер не ответит

  • @doupiu said in Помогите оптимизировать код (запросы к БД):

    Поэтому и был создан данный топик, думал пообщаться с теми, кто работает с mongodb BAS-овской.

    Работают, но лучше не надо. Рано или поздно проблем огребешь.

    Другое дело, что альтернатив в BAS для тех, кто не умеет кодить, нет.

  • @UserTrue said in Помогите оптимизировать код (запросы к БД):

    Да тогда уж проще реализовать longpolling к источнику данный которые присылает данные в БД, то есть делается запроса без таймаута и висит пока сервер не ответит

    А что будет, если данные так и не появятся?

  • @sergerdn said in Помогите оптимизировать код (запросы к БД):

    @UserTrue said in Помогите оптимизировать код (запросы к БД):

    Да тогда уж проще реализовать longpolling к источнику данный которые присылает данные в БД, то есть делается запроса без таймаута и висит пока сервер не ответит

    А что будет, если данные так и не появятся?

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

  • @UserTrue said in Помогите оптимизировать код (запросы к БД):

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

    У меня есть смутное ощущение, что так как топикастер сказал что он хочет сделать и даже в чем то как, но не написал зачем, то может быть ему нужно совсем не это.

    @doupiu поделишься, что делаешь то?

  • @sergerdn said in Помогите оптимизировать код (запросы к БД):

    @doupiu поделишься, что делаешь то?

    В принципе, в исходном сообщении все описано подробно для решения задачи, на мой взгляд, но вот еще чуть подробностей)

    Скрипт проверяет наличие товара в интернет-магазине в 50 потоков. Задержка между каждыми проверками внутри потока - 10 сек. При этом, если какой-то поток увидел, что товар есть в наличии, он записывает это в БД. С этого момента все потоки из режима "проверяем наличие" переходят в режим "покупаем товар". Именно для этого сделан цикл, который представлен в исходном сообщении. То есть каждый поток либо ждет 10 сек, чтобы сделать следующую проверку наличия, либо моментально покупает товар, так как наличие уже нашел другой поток.

    P.S. Очевидное решение - вообще исключить отсюда БД и сделать глобалку наличия, которую постоянно проверять в цикле. Но там все несколько сложнее и БД все равно нужна.

  • This post is deleted!
  • @doupiu said in Помогите оптимизировать код (запросы к БД):

    С этого момента все потоки из режима "проверяем наличие" переходят в режим "покупаем товар".

    Не проще использовать ресурс или глобальную переменную

  • @UserTrue said in Помогите оптимизировать код (запросы к БД):

    Не проще использовать ресурс или глобальную переменную

    Как и написал, решение очевидное, но не подходящее, к сожалению. Товаров не 1, а сотня. У каждого товара есть еще десяток параметров, влияющих на дальнейшую работу скрипта. Поэтому все хранится в БД.

  • @doupiu said in Помогите оптимизировать код (запросы к БД):

    @UserTrue said in Помогите оптимизировать код (запросы к БД):

    Не проще использовать ресурс или глобальную переменную

    Как и написал, решение очевидное, но не подходящее, к сожалению. Товаров не 1, а сотня. У каждого товара есть еще десяток параметров, влияющих на дальнейшую работу скрипта. Поэтому все хранится в БД.

    Если все скрипты работают на одном сервере:

    1. Стартуют потоки с поиском товара.
    2. Товар найден, данные пишутся в базу.
    3. Этот же скрипт запускает любым способом другой функционал, который покупает этот товар. Например, это может быть функция в BAS.

    Вероятно, изначально был написан скрипт с поиском товара, потом с его покупкой. И это все отдельные сущности.
    Потом между ними поставили БД для обмена информацией. Но возникли нюансы.

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

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

    Чтобы приобрести такой навык, нужен опыт. Иначе придется постоянно переделывать что-то, что бывает мучительно.

  • @doupiu said in Помогите оптимизировать код (запросы к БД):

    @UserTrue said in Помогите оптимизировать код (запросы к БД):

    Не проще использовать ресурс или глобальную переменную

    Как и написал, решение очевидное, но не подходящее, к сожалению. Товаров не 1, а сотня. У каждого товара есть еще десяток параметров, влияющих на дальнейшую работу скрипта. Поэтому все хранится в БД.

    Если товаров сотня, то использовать глобальную переменную возможно, а вот если объёмов товара больше, то только бд. Создайте массив с объектами со свойствами, как столбцы в базе данных. При добавлении данных в базу дублируйте данные в глобальную переменную.

    Ограничивайте количество элементов в массиве, например держите не более 100 элементов. Также можете сохранить хеш объекта в отдельное место, например во вторую глобальную переменную. Это нужно, что бы потоки ждали изменения хеша при добавлении новых данных, а не выполняли проверку по кругу со старыми данными.

  • @Fox said in Помогите оптимизировать код (запросы к БД):

    Если товаров сотня, то использовать глобальную переменную возможно,

    Можно хранить в глобальной переменной только id товара в базе. Тогда будет существенная экономия памяти.

  • @sergerdn said in Помогите оптимизировать код (запросы к БД):

    @Fox said in Помогите оптимизировать код (запросы к БД):

    Если товаров сотня, то использовать глобальную переменную возможно,

    Можно хранить в глобальной переменной только id товара в базе. Тогда будет существенная экономия памяти.

    Если необходим поиск по каким то параметрам, то их лучше добавить в объекты

  • @Fox said in Помогите оптимизировать код (запросы к БД):

    @sergerdn said in Помогите оптимизировать код (запросы к БД):

    @Fox said in Помогите оптимизировать код (запросы к БД):

    Если товаров сотня, то использовать глобальную переменную возможно,

    Можно хранить в глобальной переменной только id товара в базе. Тогда будет существенная экономия памяти.

    Если необходим поиск по каким то параметрам, то их лучше добавить в объекты

    Я бы все равно добавлял только id товара, а в скрипте покупки уже дергал бы из базы и делал нужные проверки. Так как, вероятно, там уже это все есть.

    Но это на усмотрение конкретного девелопера.

  • @Fox said in Помогите оптимизировать код (запросы к БД):

    @doupiu said in Помогите оптимизировать код (запросы к БД):

    @UserTrue said in Помогите оптимизировать код (запросы к БД):

    Не проще использовать ресурс или глобальную переменную

    Как и написал, решение очевидное, но не подходящее, к сожалению. Товаров не 1, а сотня. У каждого товара есть еще десяток параметров, влияющих на дальнейшую работу скрипта. Поэтому все хранится в БД.

    Если товаров сотня, то использовать глобальную переменную возможно, а вот если объёмов товара больше, то только бд. Создайте массив с объектами со свойствами, как столбцы в базе данных. При добавлении данных в базу дублируйте данные в глобальную переменную.

    Какая разница сколько их, можно все так же использовать ресурс в котором каждый товар это будет json строка и тп, вариантов масса. Это лучше чем 50 потоков долбят бедную БД. А еще обращение к встроенной БД синхронное!! тоесть все 50 потоков не могут одновременно к ней обратиться. Я думаю это было сделано для упрощения взаимодействия не особо продвинутых юзеров. Фактически при очень частых обращениях как у вас это приведет к сильному снижение скорости работы скрипта и подвисаниям интерфейса

  • @Fox @sergerdn @UserTrue спасибо за пищу для размышлений

    Пока придумал такую архитектуру: при появлении товара в наличии вместе с изменением БД изменяем глобальную переменную IS_EXISTS_STOCK c false на true, что фактически сообщает нам, что "что-то в БД поменялось". Цикл соответственно постоянно проверяет только IS_EXISTS_STOCK, и только когда IS_EXISTS_STOCK=true - уже лезет в БД выяснять, что там изменилось.

    Посмотрим :)