PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи

Страниц (1): [1]

> Найдено сообщений: 7
Sheehave Отправлено: 16 Мая, 2015 - 12:10:57 • Тема: Оптимизация категоризированного поиска товаров. • Форум: Хранение данных, их вывод и обработка

Ответов: 24
Просмотров: 3692
MAXUS пишет:
Интуиция подсказывает, что ход мыслей не правильный. 80 запросов - этому явный признак.

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

И опять же те 80 запросов - работают по единой универсальной функции, которую и в других местах я юзаю, это тоже казалось красивым решением. Но как писали недавно на хабре - красивый код не нужен Растерялся

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

Можно ли сделать ещё большую оптимизацию - я уже не уверен Однако
Sheehave Отправлено: 15 Мая, 2015 - 21:16:53 • Тема: Оптимизация категоризированного поиска товаров. • Форум: Хранение данных, их вывод и обработка

Ответов: 24
Просмотров: 3692
MAXUS пишет:
Так надо, что все запросы в body видны?

Это я прямо сейчас внедрял правки по советам Подмигивание

MAXUS пишет:
Если я правильно понимаю, слева в меню все равно количество товаров в категории выводится без учета текущих фильтров

А вот это как раз и не так, увы Огорчение

Каждый пункт слева добавляет что-то к фильтру - и на каждый новый запрос, о чём я и написал в первом вопросе. В сумме их и выходит 30-80 штук.

MAXUS пишет:
ЗЫ Да и с комбинациями категорий теоретически можно заморочиться

Вот как раз подобное решение мы и обсуждали на пхп-клабе. Оно реально должно помочь, особенно для меню слева. Но оно требует регулярного перестроения огромного обратного индекса, потому пока экспериментирую с "прямыми" решениями Растерялся
Sheehave Отправлено: 15 Мая, 2015 - 18:49:11 • Тема: Оптимизация категоризированного поиска товаров. • Форум: Хранение данных, их вывод и обработка

Ответов: 24
Просмотров: 3692
По результатам тестов могу сказать, что реализация на джойнах не даёт существенного преимущества, а вот вариант Мелкий с групповыми функциями и хевингами действительно работает в 2 раза быстрее - за что ему большое спасибо Улыбка
Sheehave Отправлено: 13 Мая, 2015 - 23:35:35 • Тема: Оптимизация категоризированного поиска товаров. • Форум: Хранение данных, их вывод и обработка

Ответов: 24
Просмотров: 3692
Мелкий пишет:

Что в запросе при этом меняется? Это вполне можно одним запросом вытащить.

Было бы круто до одного запроса Хорошо

Но там добавляется к выборке ещё один параметр - иногда из той же категории, иногда из другой. Так что разве что запросом с пользовательской функцией, что будет внутри сама собирать и исполнять SQL-код (у Оракла видел, у mysql даже не знаю)

Мелкий пишет:

Аккурат вместо имеющегося уникального по паре property_id, product_id и сделать первичный.


Попробовал снести автоинкремент первичный и поставить этот - что-то только добавилось времени) а в чём преимущество? Улыбка
Sheehave Отправлено: 13 Мая, 2015 - 23:04:14 • Тема: Оптимизация категоризированного поиска товаров. • Форум: Хранение данных, их вывод и обработка

Ответов: 24
Просмотров: 3692
Мелкий пишет:
А субд какая?
Для mysql этот запрос дико тяжёлый

Да, mysql. Сам я шарю базы данных не так хорошо, чтобы знать такие важные детали - потому ориентируюсь скорее на чужие примеры и читабельность кода Закатив глазки На работе часто приходится править код на Oracle - там сабселекты широко используют)

Sail пишет:
сравните с этим:


CODE (SQL):
скопировать код в буфер обмена
  1.  SELECT p.* FROM `products` p
  2.      JOIN `products_properties` ppts ON ppts.product_id = p.`id` AND ppts.`property_id` IN (1, 4)
  3.      JOIN `products_properties` ppts2 ON ppts2.product_id = p.`id` AND ppts2.`property_id` IN (2, 3, 6)
  4.      JOIN `products_properties` ppts3 ON ppts3.product_id = p.`id` AND ppts3.`property_id` IN (5)
  5.      GROUP BY p.`id`;



Хм, вот где-то так я написал изначально, только джойнил снова сабселекты зачем-то Однако Так что потом всё переписал на то что приводил выше. Выглядит логично, спасибо.

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


CODE (SQL):
скопировать код в буфер обмена
  1.     SELECT p.*
  2.             FROM products p
  3.             JOIN (
  4.                             SELECT product_id,
  5.                                     sum(property_id IN (1,4)) AS filter_0,
  6.                                     sum(property_id IN (2,3,6)) AS filter_1,
  7.                                     sum(property_id IN (5)) AS filter_3
  8.                             FROM products_properties
  9.                             WHERE property_id IN (1,2,3,4,5,6)
  10.                             GROUP BY produnct_id
  11.                             HAVING filter_0>0 AND filter_1>0 AND filter_2>0
  12.                             ) AS filters ON p.id=filters.product_id



Ну или такой вариант Улыбка
Вот тоже изначально подумывал о чём-то подобном. но решил что всякие сабселекты\джойны быстрее групповых функций Однако Выходит, был не прав Закатив глазки

Мелкий пишет:
Sail пишет:
добавьте индекс (уникальный

Первичный сразу.

Индексы само собой, и по property_id, и по product_id для админки, и уникальный по паре property_id, product_id

А вот на счёт первичного я немного не понял - что property_id, что product_id, всё неуникальные записи для таблицы, нет какого-то готового поля, которое бы однозначно определяло запись.
Sheehave Отправлено: 13 Мая, 2015 - 16:52:23 • Тема: Оптимизация категоризированного поиска товаров. • Форум: Хранение данных, их вывод и обработка

Ответов: 24
Просмотров: 3692
Количество страниц ограничили до 3000 с около миллиона, добавив ряд логичных ограничений, раньше оно росло факториально от количества параметров Подмигивание
Количество страниц скорее вытекает из числа комбинаций параметров на странице http://begift[dot]com[dot]ua/chto-podarit/

Изначально они вообще генерировались "на лету" и никак отдельно в базе не хранились. "Кеширование" - это и есть такая же генерация.

Кода много и база большая, попробую описать общую схему.

Мелкий пишет:
Из чего это вытекает?

При поиске слева пишут сколько товаров прибавится или убавится с добавлением параметра - вот на каждый такой параметр и происходит перерасчёт.


DeepVarvar пишет:

properties
id, title

products
id, ..., ..., ...

products_properties
property_id, product_id

Это самая простая и логичная схема, у нас та же структура, за исключением добавившихся категорий:

properties
id,categoty_id, title

products_properties
property_id,categoty_id, product_id

Вся загвоздка в том, что тут идёт комбинация "И" и "ИЛИ"

Например:
На входе имеем поиск по набору параметров
1,2,3,4,5,6

Параметры разбиты по категориям вроде:

1: {1,4},
2: {2,3,6},
3: {5}

На что я генерю SQL вида:

CODE (SQL):
скопировать код в буфер обмена
  1.     SELECT p.*
  2.         FROM products p
  3.         WHERE 1=1
  4.         AND EXISTS (SELECT 1 FROM products_properties ppts WHERE p.id = ppts.product_id AND ppts.property_id IN (1,4)   )
  5.         AND EXISTS (SELECT 1 FROM products_properties ppts WHERE p.id = ppts.product_id AND ppts.property_id IN (2,3,6)   )
  6.         AND EXISTS (SELECT 1 FROM products_properties ppts WHERE p.id = ppts.product_id AND ppts.property_id IN (5)   )


И вот сильно лучше ничего в голову не приходит.


MiksIr пишет:
Я правильно понял, что у вас фильтры по принципу яндекс-маркета, т.е. включив один фильтр вы рассчитываете активность фильтров из других групп?

Где-то так)

Сейчас посмотрю конечно что там за готовые решения предлагают. Изначально не предполагал, что это понадобится - задача вроде несложная Однако
Sheehave Отправлено: 13 Мая, 2015 - 15:54:04 • Тема: Оптимизация категоризированного поиска товаров. • Форум: Хранение данных, их вывод и обработка

Ответов: 24
Просмотров: 3692
Добрый день.

Столкнулся с проблемой скорости загрузки страниц на каталогах подарков 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 часов.

Хочу провести сравнительные тесты разных альтернативных алгоритмов. Возможно, у кого-то есть опыт в таких задачах. Буду благодарен за совет.

Страниц (1): [1]
Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB