Интуиция подсказывает, что ход мыслей не правильный. 80 запросов - этому явный признак.
Да точно неправильный, сейчас я многие функции переписываю на один запрос. База на локалхосте - я особо не переживал за число запросов, да и таким стилем можно было юзать малое число подготовленных запросов с переменными параметрами - что тоже красиво выглядело.
И опять же те 80 запросов - работают по единой универсальной функции, которую и в других местах я юзаю, это тоже казалось красивым решением. Но как писали недавно на хабре - красивый код не нужен
Так что MiksIr дело говорит, это мой следующих шаг - разбить выборки на пару частных случаев и запрашивать по максимуму одним селектом. Можно даже все новые категории в один селект брать.
Можно ли сделать ещё большую оптимизацию - я уже не уверен
Если я правильно понимаю, слева в меню все равно количество товаров в категории выводится без учета текущих фильтров
А вот это как раз и не так, увы
Каждый пункт слева добавляет что-то к фильтру - и на каждый новый запрос, о чём я и написал в первом вопросе. В сумме их и выходит 30-80 штук.
MAXUS пишет:
ЗЫ Да и с комбинациями категорий теоретически можно заморочиться
Вот как раз подобное решение мы и обсуждали на пхп-клабе. Оно реально должно помочь, особенно для меню слева. Но оно требует регулярного перестроения огромного обратного индекса, потому пока экспериментирую с "прямыми" решениями
По результатам тестов могу сказать, что реализация на джойнах не даёт существенного преимущества, а вот вариант Мелкий с групповыми функциями и хевингами действительно работает в 2 раза быстрее - за что ему большое спасибо
Что в запросе при этом меняется? Это вполне можно одним запросом вытащить.
Было бы круто до одного запроса
Но там добавляется к выборке ещё один параметр - иногда из той же категории, иногда из другой. Так что разве что запросом с пользовательской функцией, что будет внутри сама собирать и исполнять SQL-код (у Оракла видел, у mysql даже не знаю)
Мелкий пишет:
Аккурат вместо имеющегося уникального по паре property_id, product_id и сделать первичный.
Попробовал снести автоинкремент первичный и поставить этот - что-то только добавилось времени) а в чём преимущество?
Да, mysql. Сам я шарю базы данных не так хорошо, чтобы знать такие важные детали - потому ориентируюсь скорее на чужие примеры и читабельность кода На работе часто приходится править код на Oracle - там сабселекты широко используют)
JOIN`products_properties` ppts ON ppts.product_id = p.`id`AND ppts.`property_id`IN(1, 4)
JOIN`products_properties` ppts2 ON ppts2.product_id = p.`id`AND ppts2.`property_id`IN(2, 3, 6)
JOIN`products_properties` ppts3 ON ppts3.product_id = p.`id`AND ppts3.`property_id`IN(5)
GROUPBY p.`id`;
Хм, вот где-то так я написал изначально, только джойнил снова сабселекты зачем-то Так что потом всё переписал на то что приводил выше. Выглядит логично, спасибо.
Мелкий пишет:
Идентичный запрос и должен быть уже ощутимо легче, чтобы сразу в рантайме считаться:
Ну или такой вариант
Вот тоже изначально подумывал о чём-то подобном. но решил что всякие сабселекты\джойны быстрее групповых функций Выходит, был не прав
Мелкий пишет:
Sail пишет:
добавьте индекс (уникальный
Первичный сразу.
Индексы само собой, и по property_id, и по product_id для админки, и уникальный по паре property_id, product_id
А вот на счёт первичного я немного не понял - что property_id, что product_id, всё неуникальные записи для таблицы, нет какого-то готового поля, которое бы однозначно определяло запись.
Количество страниц ограничили до 3000 с около миллиона, добавив ряд логичных ограничений, раньше оно росло факториально от количества параметров
Количество страниц скорее вытекает из числа комбинаций параметров на странице http://begift[dot]com[dot]ua/chto-podarit/
Изначально они вообще генерировались "на лету" и никак отдельно в базе не хранились. "Кеширование" - это и есть такая же генерация.
Кода много и база большая, попробую описать общую схему.
Мелкий пишет:
Из чего это вытекает?
При поиске слева пишут сколько товаров прибавится или убавится с добавлением параметра - вот на каждый такой параметр и происходит перерасчёт.
DeepVarvar пишет:
properties
id, title
products
id, ..., ..., ...
products_properties
property_id, product_id
Это самая простая и логичная схема, у нас та же структура, за исключением добавившихся категорий:
Столкнулся с проблемой скорости загрузки страниц на каталогах подарков http://begift[dot]ru/ и http://begift[dot]com[dot]ua/ На сайте каждый товар имеет ряд параметров, которые его характеризуют. Параметры, в свою очередь, разбиты по категориям. Например, товар: цветы имеют параметры «Праздник» – 8 Марта, 14 Февраля… и «Кому подарить»: Маме, Жене, Девушке и т.д. Пользователь может свободно комбинировать параметры, на основе которых ему показываются подходящие товары. Пытаюсь оптимизировать данную страницу, поскольку время генерации составляет неприличные 10-15 сек: http://tools[dot]pingdom[dot]com/fpt/#!/[dot][dot][dot]god-iz-igrushek/
Подбор товара осуществляется алгоритмом: параметры внутри категории объединяются оператором ИЛИ, сами категории – оператором И. Страница, кроме основного списка, показывает также количество подарков, которое будет получено путем комбинирования уже выбранных и дополнительных параметров. Этот расчет также происходит по тому же алгоритму. Таким образом, мы имеем около 30 таких выборок на каждую загрузку страницы. В большинстве случаев используем подготовленные запросы, но для таких страниц запрос полностью генерируется в php коде вместе с параметрами. Он довольно объемный и плохо оптимизируется с самой базой. Я уже реализовал кэширование (сохраняя результаты всех вычислений для каждой страницы) на стороне сервера. Так как стоимость товара и его наличие обновляется, то этот кэш нужно обновлять раз в 1-2 дня. Страниц около 3000, если кэшировать каждую каждый день, то только на кэширование уйдет 10 часов.
Хочу провести сравнительные тесты разных альтернативных алгоритмов. Возможно, у кого-то есть опыт в таких задачах. Буду благодарен за совет.