Имеются данные, приходящие из БД в формате:
- id
- payload (json)
После получения данных и некоторых условий у меня начинается цикл foreach, где каждый элемент payload обрабатывается через json_decode. Проблема в том, что json_decode выполняется около 90% всего времени запроса, что является очень узким горлышком алгоритма. Т.е. выполнение всего алгоритма (запроса) выполняется, к примеру, 20 секунд, а обработка json_decode выполняется за 18 секунд. Что не есть хорошо.
Вопрос собственно в следующем: можно ли как-то этот json_decode ускорить?
PS: Использование кеша (redis и т.п.) не возможно из-за ограниченных ресурсов сервера и большого количества данных (при этом постоянно меняющихся).
UPD:
Для понимания алгоритма быстренько опишу его:
С множества документов (ERP система) в одну таблицу собираются определённые данные с вложенностями и записывается это всё в json, что бы дальше было удобно работать с ним. В отчёте (где всё это должно отобразиться) - получаем все эти данные и отображаем с определёнными условиями (фильтрами).
Сказать то легко, а вот сделать сложнее. Так как переделывать придётся много где (около 50 документов/контроллеров, модели и т.п.)
Вот пока до этого не дошло - ищу более лёгкие в реализации варианты.
Всё относительно. Для алгоритма (который был уже написан) - это хорошее решение. Но с постоянно увеличивающейся БД - обрабатывать это через json_decode становится всё более затратным по времени.
вам на самом деле нужна документная база (та же MongoDB, например)
Возможно это было бы не плохо взять, но в самом начале разработки. А переносить это сейчас на другую БД будет слишком затратно в человеко-часах. Да и сложно это будет уже внедрять. И то ещё не факт что поможет.
И спасибо за этот вопрос.
Его можно и нужно использовать, чтобы бить об него головой всех нубов, а заодно всех местных помогаек, которые сначала "я и сам лучше всех знаю, как делать", а потом "ой, а база растёт, аказываица"
Lynn «Кофеман», с каких пор монга подходит для хранения иерархических данных? (не то чтобы она подходила вообще хоть для чего-нибудь, но в данном случае это особенно непонятно)
Дмитрий Кузнецов, в любом проекте, который активно развивается, время от времени появляется необходимость рефакторинга - что-то не учили или просто изменились бизнес требования. Это нормально. А затягивание необходимых изменений будет приводить к деградации, как по производительности, так и по качеству кода.
Но с постоянно увеличивающейся БД - обрабатывать это через json_decode становится всё более затратным по времени.
Каким образом растущая база влияет на парсинг конкретного json?
Сказать то легко, а вот сделать сложнее. Так как переделывать придётся много где (около 50 документов/контроллеров, модели и т.п.)
Если код нормальный, то не нужно переделывать контроллеры, бизнес-модели и документы, только модели отвечающие за хранение данных в БД. Или тут тоже накосячено?
Vitsliputsli, проблема не в парсинге конкретно, а в том, что данные изначально хранятся в джейсон и поэтому приходится по очереди распаковывать всё подряд, чтобы найти нужные.
То есть здесь не только нубский зашквар - перебрать всю таблицу, чтобы достать одну запись - в который даже джунов мордочкой тычут, но к нему добавляется ещё и постоянная распаковка джейсона.
поэтому приходится по очереди распаковывать всё подряд, чтобы найти нужные
Не совсем так. По средствам Postgresql и laravel (php по сути) делаем выборку из +100к данных. А после, в цикле, начинается парсинг JSON поля и подсчитывание из него различных данных с дальнейшем отображении на сайте в виде дерева. Из-за этого такая структура.
Но вот избавиться от идиотского алгоритма, который чтобы достать одну запись декодит их все по очереди - можно и нужно.
И никакой детский лепет про "ой заранее распарсить ну никак нельзя, сайт крутится на мамином утюге" здесь не помеха.
Распарсить, положить в базу, при изменении данных менять их в базе, искать по-человечески, через SQL.
А редис тут вообще никаким боком не упёрся.
да, нельзя. в бд не получится храниить сразу отдельно в колонках, так как нельзя делать вложенности данных (не используя другие таблицы, как я понимаю). так как сейчас в бд хранится дерево вложенностей, доходящее до 5-6 уровней.
Да можно, можно. Всё можно.
И дерево хранить, и всё что угодно.
Надо просто поставить эту задачу, и она прекрасно решится. Потому что именно так это и делается во всём мире.
Но сначала надо поменять неверные установки, что "оптимизировать исходно идиотский алгоритм можно, а использовать правильный подход нельзя". Потому что всё как раз наоборот.
Я понимаю что вы начинающий программист, и у вас в голове нет четкого понимания этих вещей. Но сейчас ваш вопрос звучит как "Помогите надеть штаны на голову, всё время на глаза сползают. Нет, на ноги надеть не получится".
FanatPHP, в итоге было решено в тестовом варианте немного переписать алгоритм. Таким образом, все проверки в цикле переместятся в sql запрос. Это снизит расчётное время проверок на php.
Получится ли тем самым хорошо оптимизировать алгоритм - точно не знаю, в любом случае ускорение будет.
FanatPHP
UPD: Все проверки (jsonb поля) перенесены в SQL, тем самым получилось очень хорошо оптимизировать формирование отчёта.
Раньше отчёт за 1 последний год формировался около 10 минут, теперь формируется за +-10 сек. А за весь промежуток времени он формируется за 30-40 сек.
Можно попробовать использовать либу для потокового парсинга json halaxa/json-machine. Она вам поможет убедиться что проблема не в парсинге, а в структуре базы