Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757
Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737 Форумы портала PHP.SU :: Оптимизация категоризированного поиска товаров. [2]
Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009 Откуда: Россия, Санкт-Петербург
Помог: 618 раз(а)
Данке, исправил.
----- PostgreSQL DBA
Sheehave
Отправлено: 13 Мая, 2015 - 23:04:14
Новичок
Покинул форум
Сообщений всего: 7
Дата рег-ции: Май 2015
Помог: 0 раз(а)
Мелкий пишет:
А субд какая?
Для mysql этот запрос дико тяжёлый
Да, 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, всё неуникальные записи для таблицы, нет какого-то готового поля, которое бы однозначно определяло запись.
Мелкий
Отправлено: 13 Мая, 2015 - 23:22:23
Активный участник
Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009 Откуда: Россия, Санкт-Петербург
Помог: 618 раз(а)
Sheehave пишет:
А вот на счёт первичного я немного не понял - что property_id, что product_id, всё неуникальные записи для таблицы, нет какого-то готового поля, которое бы однозначно определяло запись.
Аккурат вместо имеющегося уникального по паре property_id, product_id и сделать первичный.
Sheehave пишет:
на Oracle - там сабселекты широко используют)
Ну там они и работают нормально и оптимизируются хорошо.
То, что в mysql называют оптимизатором запроса, в нормальных СУБД выполняется ещё до оптимизатора
----- PostgreSQL DBA
Sheehave
Отправлено: 13 Мая, 2015 - 23:35:35
Новичок
Покинул форум
Сообщений всего: 7
Дата рег-ции: Май 2015
Помог: 0 раз(а)
Мелкий пишет:
Что в запросе при этом меняется? Это вполне можно одним запросом вытащить.
Было бы круто до одного запроса
Но там добавляется к выборке ещё один параметр - иногда из той же категории, иногда из другой. Так что разве что запросом с пользовательской функцией, что будет внутри сама собирать и исполнять SQL-код (у Оракла видел, у mysql даже не знаю)
Мелкий пишет:
Аккурат вместо имеющегося уникального по паре property_id, product_id и сделать первичный.
Попробовал снести автоинкремент первичный и поставить этот - что-то только добавилось времени) а в чём преимущество?
Покинул форум
Сообщений всего: 7
Дата рег-ции: Май 2015
Помог: 0 раз(а)
По результатам тестов могу сказать, что реализация на джойнах не даёт существенного преимущества, а вот вариант Мелкий с групповыми функциями и хевингами действительно работает в 2 раза быстрее - за что ему большое спасибо
MAXUS
Отправлено: 15 Мая, 2015 - 20:29:37
Посетитель
Покинул форум
Сообщений всего: 329
Дата рег-ции: Апр. 2011
Помог: 7 раз(а)
Sheehave пишет:
По результатам тестов могу сказать, что реализация на джойнах не даёт существенного преимущества, а вот вариант Мелкий с групповыми функциями и хевингами действительно работает в 2 раза быстрее - за что ему большое спасибо
Вопросы:
1. Так надо, что все запросы в body видны?
2. Если я правильно понимаю, слева в меню все равно количество товаров в категории выводится без учета текущих фильтров. Зачем тогда огород городить? Просто создать таблицу, в которой фиксировать количество товара в категории. Принцип лучше посчитать один раз и сохранить, чем каждый раз пересчитывать. Летать будет.
ЗЫ Да и с комбинациями категорий теоретически можно заморочиться. Как вариант... В таблице, которая хранит количество товаров по категории, ключ делаешь хэшем из комбинации категорий. Сохраняешь при записи товарной позиции (или при присвоении товару категории).
Типа hash = для сына+солидный+на день рождения. Только при создании ключа сортируешь свойства определенным образом. Например, по алфавиту. Тогда hash в примере перестроится на для сына+на день рождения+солидный...
ЗЗЫ А вообще, судя по тому, что у тебя в body генерится более 80 запросов, ты что-то явно делаешь не так и оптимизация заключается как раз в том, чтобы этот косяк выкупить. Подозреваю, что после этого у тебя и без специальных таблиц летать будет.
Покинул форум
Сообщений всего: 7
Дата рег-ции: Май 2015
Помог: 0 раз(а)
MAXUS пишет:
Так надо, что все запросы в body видны?
Это я прямо сейчас внедрял правки по советам
MAXUS пишет:
Если я правильно понимаю, слева в меню все равно количество товаров в категории выводится без учета текущих фильтров
А вот это как раз и не так, увы
Каждый пункт слева добавляет что-то к фильтру - и на каждый новый запрос, о чём я и написал в первом вопросе. В сумме их и выходит 30-80 штук.
MAXUS пишет:
ЗЫ Да и с комбинациями категорий теоретически можно заморочиться
Вот как раз подобное решение мы и обсуждали на пхп-клабе. Оно реально должно помочь, особенно для меню слева. Но оно требует регулярного перестроения огромного обратного индекса, потому пока экспериментирую с "прямыми" решениями
MAXUS
Отправлено: 16 Мая, 2015 - 08:16:56
Посетитель
Покинул форум
Сообщений всего: 329
Дата рег-ции: Апр. 2011
Помог: 7 раз(а)
Sheehave пишет:
Каждый пункт слева добавляет что-то к фильтру - и на каждый новый запрос, о чём я и написал в первом вопросе. В сумме их и выходит 30-80 штук.
А ты можешь ТЗ поподробнее сформулировать? Простыми словами, что конкретно требуется? Без привязки к реализации. Типа сначала слева категории такие-то. В листинге соответственно картинки. Ткнули на картинку, как должна изменяться менюха слева и что должны получить в листинге? И т.д. Просто заинтересовала задача. Интуиция подсказывает, что ход мыслей не правильный. 80 запросов - этому явный признак.
Покинул форум
Сообщений всего: 378
Дата рег-ции: Сент. 2014
Помог: 10 раз(а)
[+]
Вообще-то у тебя должен быть один запрос на каждую группу с акивными (выбранными) фильтрами - что бы найти число вариантов по этой группе (влияние на нее других включенных фильтров) + 1 запрос для всех остальных групп фильтров. Ну и сам запрос на выборку товара, хотя тут можно тупо по ID выбирать.
У тебя 7 групп - т.е. _максимум_ 7 запросов + запрос на сами товары.
Откуда 80 то?
----- self-banned
Sheehave
Отправлено: 16 Мая, 2015 - 12:10:57
Новичок
Покинул форум
Сообщений всего: 7
Дата рег-ции: Май 2015
Помог: 0 раз(а)
MAXUS пишет:
Интуиция подсказывает, что ход мыслей не правильный. 80 запросов - этому явный признак.
Да точно неправильный, сейчас я многие функции переписываю на один запрос. База на локалхосте - я особо не переживал за число запросов, да и таким стилем можно было юзать малое число подготовленных запросов с переменными параметрами - что тоже красиво выглядело.
И опять же те 80 запросов - работают по единой универсальной функции, которую и в других местах я юзаю, это тоже казалось красивым решением. Но как писали недавно на хабре - красивый код не нужен
Так что MiksIr дело говорит, это мой следующих шаг - разбить выборки на пару частных случаев и запрашивать по максимуму одним селектом. Можно даже все новые категории в один селект брать.
Можно ли сделать ещё большую оптимизацию - я уже не уверен
Все гости форума могут просматривать этот раздел. Только зарегистрированные пользователи могут создавать новые темы в этом разделе. Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.