Категории c неограниченной вложенностью (более 8к)

Обсуждение документации второй версии фреймворка. Переводы Cookbook и авторские рецепты.
Wizard
Сообщения: 156
Зарегистрирован: 2018.02.05, 13:41
Контактная информация:

Категории c неограниченной вложенностью (более 8к)

Сообщение Wizard » 2018.02.08, 01:06

изначально стал вопрос viewtopic.php?f=19&t=46542 о медленной работе where() с большими массивами

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

Аватара пользователя
SiZE
Сообщения: 2587
Зарегистрирован: 2011.09.21, 12:39
Откуда: Perm
Контактная информация:

Re: Категории c неограниченной вложенностью (более 8к)

Сообщение SiZE » 2018.02.08, 04:52

а банально?

Код: Выделить всё

->andWhere(new Expression("id IN (".implode(',', $ids).")"));

Wizard
Сообщения: 156
Зарегистрирован: 2018.02.05, 13:41
Контактная информация:

Re: Категории c неограниченной вложенностью (более 8к)

Сообщение Wizard » 2018.02.08, 14:26

SiZE писал(а):
2018.02.08, 04:52
а банально?

Код: Выделить всё

->andWhere(new Expression("id IN (".implode(',', $ids).")"));
да, запрос для выборки товаров именно так и сделал.

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

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

я на данный момент делаю выборку всех категорий, создаю два массива - все категории и массив с дочерними категориями (parent_id => [childrensIds]).

вот и возник вопрос - какие варианты могут быть еще

Аватара пользователя
SiZE
Сообщения: 2587
Зарегистрирован: 2011.09.21, 12:39
Откуда: Perm
Контактная информация:

Re: Категории c неограниченной вложенностью (более 8к)

Сообщение SiZE » 2018.02.08, 14:51

Я бы все же вернулся к постановке задачи. Если вам потребовалось сделать выборку из 8000 id в одном запросе, надо спросить ЧЯДНТ?

Wizard
Сообщения: 156
Зарегистрирован: 2018.02.05, 13:41
Контактная информация:

Re: Категории c неограниченной вложенностью (более 8к)

Сообщение Wizard » 2018.02.08, 15:00

SiZE писал(а):
2018.02.08, 14:51
надо спросить ЧЯДНТ?
?
SiZE писал(а):
2018.02.08, 14:51
Я бы все же вернулся к постановке задачи. Если вам потребовалось сделать выборку из 8000 id в одном запросе, надо спросить ЧЯДНТ?
задача не сделать выборку 8к идов а в том что бы построить из них дерево категорий, для начала, а в идеале еще и посчитать в каких есть товары(с определенными параметрами) и что бы при работе без кеша ответ от сервера был удовлетворителен.

Аватара пользователя
ElisDN
Сообщения: 5015
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Категории c неограниченной вложенностью (более 8к)

Сообщение ElisDN » 2018.02.08, 15:04

Ещё вариант - переделать категории в NestedSets или что то подобное и делать одним запросом:

Код: Выделить всё

SELECT p.* FROM products p LEFT JOIN categories c ... WHERE c.lft >= :lft AND c.rgt <= :rgt

Wizard
Сообщения: 156
Зарегистрирован: 2018.02.05, 13:41
Контактная информация:

Re: Категории c неограниченной вложенностью (более 8к)

Сообщение Wizard » 2018.02.08, 15:05

ElisDN писал(а):
2018.02.08, 15:04
Ещё вариант - переделать категории в NestedSets или что то подобное и делать одним запросом:

Код: Выделить всё

SELECT p.* FROM products p LEFT JOIN categories c ... WHERE c.lft >= :lft AND c.rgt <= :rgt
с самим запросом проблем нет)) вопрос что делать после него))

Wizard
Сообщения: 156
Зарегистрирован: 2018.02.05, 13:41
Контактная информация:

Re: Категории c неограниченной вложенностью (более 8к)

Сообщение Wizard » 2018.02.08, 15:07

ElisDN писал(а):
2018.02.08, 15:04
Ещё вариант - переделать категории в NestedSets или что то подобное и делать одним запросом:

Код: Выделить всё

SELECT p.* FROM products p LEFT JOIN categories c ... WHERE c.lft >= :lft AND c.rgt <= :rgt
вы кстати в Мастер-класс по Laravel анонсируете "Там мы с вами в течение месяца полностью разработаем сайт объявлений на примере сервиса Avito и ему подобных"

вот в ему подобных от 6к и выше категорий, к примеру tiu.ru как минимум на фронте есть меню из этих категорий. вот и встал вопрос - как работать с таким объемным деревом

skynin
Сообщения: 154
Зарегистрирован: 2017.12.12, 10:09

Re: Категории c неограниченной вложенностью (более 8к)

Сообщение skynin » 2018.02.08, 15:24

Wizard писал(а):
2018.02.08, 15:07
вот в ему подобных от 6к и выше категорий, к примеру tiu.ru как минимум на фронте есть меню из этих категорий. вот и встал вопрос - как работать с таким объемным деревом
Если еще и с количеством товаров в категории - то в приложении проблематично всегда.
тормоза вот с этим - я на данный момент делаю выборку всех категорий - сложно побороть.

Такое выносится в БД - оптимизированная схема БД + хранимые процедуры.

Еще вариант - опираться на особенности задачи.
Например - а нельзя ли это дерево формировать при изменении списка категорий?
Вложенность требуется точно неограниченная, или можно ограничить скажем 3мя уровнями?
и т.п.
то есть - подогнать немного саму задачу под более простое решение.

Или - дерево надо для фронтенда? Значит кешировать надо не данные для него, а сам html-json что уходит на фронтенд для его отображения.
Вложенность возможна неограниченная? так хранить путь категории, в текстовом поле, в самой БД, который перестраивается по триггеру изменения списка категорий.
И т.д.
Много вариантов.

Это обычная история и в CMS - до пары сотни категорий и 5k товара - все летает.
Как перевалит за какую-то условную 10k - все, надо тюнить.
Неврубающийся не может опознать врубающегося.

Аватара пользователя
SiZE
Сообщения: 2587
Зарегистрирован: 2011.09.21, 12:39
Откуда: Perm
Контактная информация:

Re: Категории c неограниченной вложенностью (более 8к)

Сообщение SiZE » 2018.02.08, 16:07

Wizard писал(а):
2018.02.08, 15:00
задача не сделать выборку 8к идов
Допустим. Но зачем так много выбирать за раз? Я просто к чему это.. меня как-то заставили выгрузить справочник 10+ записей, но в итоге удалось убедить заказчика, что не надо столько.

Wizard
Сообщения: 156
Зарегистрирован: 2018.02.05, 13:41
Контактная информация:

Re: Категории c неограниченной вложенностью (более 8к)

Сообщение Wizard » 2018.02.08, 16:25

SiZE писал(а):
2018.02.08, 16:07
Wizard писал(а):
2018.02.08, 15:00
задача не сделать выборку 8к идов
Допустим. Но зачем так много выбирать за раз? Я просто к чему это.. меня как-то заставили выгрузить справочник 10+ записей, но в итоге удалось убедить заказчика, что не надо столько.
дело в том что один запрос выборки всех категорий легче чем формирование хлебных крошек, к примеру на 5-м уровне вложенности, + к примеру, отобразить дочерние категории как минимум еще один запрос, по мимо того что категории необходимы для формирования дерева меню, и так далее...

skynin
Сообщения: 154
Зарегистрирован: 2017.12.12, 10:09

Re: Категории c неограниченной вложенностью (более 8к)

Сообщение skynin » 2018.02.08, 16:39

Wizard писал(а):
2018.02.08, 16:25
дело в том что один запрос выборки всех категорий легче чем формирование хлебных крошек, к примеру на 5-м уровне вложенности,
все так.
для этого даже отдельные сервера поднимают, встречал как-то у знакомых джавистов решение для OEBS для генерации урла и крошек.

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

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

Аватара пользователя
ElisDN
Сообщения: 5015
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Категории c неограниченной вложенностью (более 8к)

Сообщение ElisDN » 2018.02.08, 18:31

Wizard писал(а):
2018.02.08, 15:05
с самим запросом проблем нет)) вопрос что делать после него))
В смысле "что делать после него"?

- Один этот запрос с JOIN без IN (...) на получение товаров по подрубрикам текущей рубрики
- Один запрос на получение дерева подкатегорий текущей категории для подменю
- Один запрос на получение всех родителей текущей категории для хлебных крошек

Суть именно в том, что в Nested Sets любое поддерево или цепь родителей выбираются одним запросом без рекурсии.

Wizard
Сообщения: 156
Зарегистрирован: 2018.02.05, 13:41
Контактная информация:

Re: Категории c неограниченной вложенностью (более 8к)

Сообщение Wizard » 2018.02.08, 19:52

ElisDN писал(а):
2018.02.08, 18:31
Wizard писал(а):
2018.02.08, 15:05
с самим запросом проблем нет)) вопрос что делать после него))
В смысле "что делать после него"?

- Один этот запрос с JOIN без IN (...) на получение товаров по подрубрикам текущей рубрики
- Один запрос на получение дерева подкатегорий текущей категории для подменю
- Один запрос на получение всех родителей текущей категории для хлебных крошек

Суть именно в том, что в Nested Sets любое поддерево или цепь родителей выбираются одним запросом без рекурсии.
+ как минимум еще запрос для основного меню

итого 4 запроса. надо смотреть на цифры, что получится в итоге....

Аватара пользователя
ElisDN
Сообщения: 5015
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Категории c неограниченной вложенностью (более 8к)

Сообщение ElisDN » 2018.02.08, 20:00

Wizard писал(а):
2018.02.08, 19:52
итого 4 запроса. надо смотреть на цифры, что получится в итоге....
Итого 4 элементарных запроса по индексам.

Например, для поддерева текущей категории:

Код: Выделить всё

SELECT * FROM categories WHERE lft >= 112 AND rgt <=286 ORDER BY lft ASC
Последний раз редактировалось ElisDN 2018.02.08, 20:11, всего редактировалось 1 раз.

Wizard
Сообщения: 156
Зарегистрирован: 2018.02.05, 13:41
Контактная информация:

Re: Категории c неограниченной вложенностью (более 8к)

Сообщение Wizard » 2018.02.08, 20:05

ElisDN писал(а):
2018.02.08, 20:00
Wizard писал(а):
2018.02.08, 19:52
итого 4 запроса. надо смотреть на цифры, что получится в итоге....
Итого 4 элементарных запроса по индексам.

Например, для поддерева текущей категории:

Код: Выделить всё

SELECT * FROM categories WHERE lft >= 112 AND rgt <=286
сейчас попробую, завтра отпишусь что вышло.

Но есть вопрос - как быть с кешем? К примеру с полной выборкой я загоняю в редис 3 таблицы

- все категории id|serialize(category) (serialize по моим замерам работает быстрее чем json)
- parent_id|child_id
- url|id

предков получаю через while() дочек через рекурсию

как быть с Nested Sets?

Аватара пользователя
ElisDN
Сообщения: 5015
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Категории c неограниченной вложенностью (более 8к)

Сообщение ElisDN » 2018.02.08, 20:14

Wizard писал(а):
2018.02.08, 20:05
как быть с Nested Sets?
Например, кешируйте только URL.

Wizard
Сообщения: 156
Зарегистрирован: 2018.02.05, 13:41
Контактная информация:

Re: Категории c неограниченной вложенностью (более 8к)

Сообщение Wizard » 2018.02.08, 20:16

ElisDN писал(а):
2018.02.08, 20:14
Wizard писал(а):
2018.02.08, 20:05
как быть с Nested Sets?
Например, кешируйте только URL.
как передвигаться по иерархии исключительно по редису?

Wizard
Сообщения: 156
Зарегистрирован: 2018.02.05, 13:41
Контактная информация:

Re: Категории c неограниченной вложенностью (более 8к)

Сообщение Wizard » 2018.02.08, 20:23

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

в Nested Sets подкупает простота выборки товаров. может гибрид сочинить...)))

Wizard
Сообщения: 156
Зарегистрирован: 2018.02.05, 13:41
Контактная информация:

Re: Категории c неограниченной вложенностью (более 8к)

Сообщение Wizard » 2018.02.13, 17:59

ElisDN писал(а):
2018.02.08, 15:04
Ещё вариант - переделать категории в NestedSets или что то подобное и делать одним запросом:

Код: Выделить всё

SELECT p.* FROM products p LEFT JOIN categories c ... WHERE c.lft >= :lft AND c.rgt <= :rgt
как на счет https://github.com/paulzi/yii2-materialized-path, доводилесь работать?

Ответить