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]

 PHP.SU

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


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

> Без описания
Мелкий Супермодератор
Отправлено: 13 Мая, 2015 - 17:52:05
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




Данке, исправил.


-----
PostgreSQL DBA
 
 Top
Sheehave
Отправлено: 13 Мая, 2015 - 23:04:14
Post Id


Новичок


Покинул форум
Сообщений всего: 7
Дата рег-ции: Май 2015  


Помог: 0 раз(а)




Мелкий пишет:
А субд какая?
Для 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, всё неуникальные записи для таблицы, нет какого-то готового поля, которое бы однозначно определяло запись.
 
 Top
Мелкий Супермодератор
Отправлено: 13 Мая, 2015 - 23:22:23
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




Sheehave пишет:
А вот на счёт первичного я немного не понял - что property_id, что product_id, всё неуникальные записи для таблицы, нет какого-то готового поля, которое бы однозначно определяло запись.

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

Sheehave пишет:
на Oracle - там сабселекты широко используют)

Ну там они и работают нормально и оптимизируются хорошо.
То, что в mysql называют оптимизатором запроса, в нормальных СУБД выполняется ещё до оптимизатора Закатив глазки


-----
PostgreSQL DBA
 
 Top
Sheehave
Отправлено: 13 Мая, 2015 - 23:35:35
Post Id


Новичок


Покинул форум
Сообщений всего: 7
Дата рег-ции: Май 2015  


Помог: 0 раз(а)




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

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

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

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

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

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


Попробовал снести автоинкремент первичный и поставить этот - что-то только добавилось времени) а в чём преимущество? Улыбка

(Отредактировано автором: 13 Мая, 2015 - 23:52:29)

 
 Top
Sheehave
Отправлено: 15 Мая, 2015 - 18:49:11
Post Id


Новичок


Покинул форум
Сообщений всего: 7
Дата рег-ции: Май 2015  


Помог: 0 раз(а)




По результатам тестов могу сказать, что реализация на джойнах не даёт существенного преимущества, а вот вариант Мелкий с групповыми функциями и хевингами действительно работает в 2 раза быстрее - за что ему большое спасибо Улыбка
 
 Top
MAXUS
Отправлено: 15 Мая, 2015 - 20:29:37
Post Id


Посетитель


Покинул форум
Сообщений всего: 329
Дата рег-ции: Апр. 2011  


Помог: 7 раз(а)




Sheehave пишет:
По результатам тестов могу сказать, что реализация на джойнах не даёт существенного преимущества, а вот вариант Мелкий с групповыми функциями и хевингами действительно работает в 2 раза быстрее - за что ему большое спасибо Улыбка


Вопросы:

1. Так надо, что все запросы в body видны?
2. Если я правильно понимаю, слева в меню все равно количество товаров в категории выводится без учета текущих фильтров. Зачем тогда огород городить? Просто создать таблицу, в которой фиксировать количество товара в категории. Принцип лучше посчитать один раз и сохранить, чем каждый раз пересчитывать. Летать будет.

ЗЫ Да и с комбинациями категорий теоретически можно заморочиться. Как вариант... В таблице, которая хранит количество товаров по категории, ключ делаешь хэшем из комбинации категорий. Сохраняешь при записи товарной позиции (или при присвоении товару категории).
Типа hash = для сына+солидный+на день рождения. Только при создании ключа сортируешь свойства определенным образом. Например, по алфавиту. Тогда hash в примере перестроится на для сына+на день рождения+солидный...

ЗЗЫ А вообще, судя по тому, что у тебя в body генерится более 80 запросов, ты что-то явно делаешь не так и оптимизация заключается как раз в том, чтобы этот косяк выкупить. Подозреваю, что после этого у тебя и без специальных таблиц летать будет.

(Отредактировано автором: 15 Мая, 2015 - 20:42:46)

 
 Top
Sheehave
Отправлено: 15 Мая, 2015 - 21:16:53
Post Id


Новичок


Покинул форум
Сообщений всего: 7
Дата рег-ции: Май 2015  


Помог: 0 раз(а)




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

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

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

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

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

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

Вот как раз подобное решение мы и обсуждали на пхп-клабе. Оно реально должно помочь, особенно для меню слева. Но оно требует регулярного перестроения огромного обратного индекса, потому пока экспериментирую с "прямыми" решениями Растерялся
 
 Top
MAXUS
Отправлено: 16 Мая, 2015 - 08:16:56
Post Id


Посетитель


Покинул форум
Сообщений всего: 329
Дата рег-ции: Апр. 2011  


Помог: 7 раз(а)




Sheehave пишет:

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


А ты можешь ТЗ поподробнее сформулировать? Простыми словами, что конкретно требуется? Без привязки к реализации. Типа сначала слева категории такие-то. В листинге соответственно картинки. Ткнули на картинку, как должна изменяться менюха слева и что должны получить в листинге? И т.д. Просто заинтересовала задача. Интуиция подсказывает, что ход мыслей не правильный. 80 запросов - этому явный признак.

(Отредактировано автором: 16 Мая, 2015 - 08:29:39)

 
 Top
MiksIr
Отправлено: 16 Мая, 2015 - 11:51:04
Post Id


Забанен


Покинул форум
Сообщений всего: 378
Дата рег-ции: Сент. 2014  


Помог: 10 раз(а)

[+]


Вообще-то у тебя должен быть один запрос на каждую группу с акивными (выбранными) фильтрами - что бы найти число вариантов по этой группе (влияние на нее других включенных фильтров) + 1 запрос для всех остальных групп фильтров. Ну и сам запрос на выборку товара, хотя тут можно тупо по ID выбирать.

У тебя 7 групп - т.е. _максимум_ 7 запросов + запрос на сами товары.

Откуда 80 то?


-----
self-banned
 
 Top
Sheehave
Отправлено: 16 Мая, 2015 - 12:10:57
Post Id


Новичок


Покинул форум
Сообщений всего: 7
Дата рег-ции: Май 2015  


Помог: 0 раз(а)




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

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

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

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

Можно ли сделать ещё большую оптимизацию - я уже не уверен Однако
 
 Top
Страниц (2): « 1 [2]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« Хранение данных, их вывод и обработка »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB