|
Несколько Join таблицы саму на себя
|
|||
---|---|---|---|
#18+
Добрый день, существует 3 таблицы. Таблица product Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18.
Таблица attribute Код: sql 1. 2. 3. 4. 5. 6. 7.
Таблица product_to_attribute Код: sql 1. 2. 3. 4. 5.
В реальности имеем товары, которые содержать несколько атрибутов, 1 и больше. Необходимо получать товары по заданным атрибутам. В качестве реализации использую вот такой запрос: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29.
Если атрибутов до 5, то скорость выполнения приемлема, если 8 и больше, то скорость > 20 cек. В качестве СУБД использую MySQL 5.7.31. Записей в product > 150 000, attribute 600, product_to_attribute > 500 000 и база будет расти. Не могли бы вы подсказать или натолкнуть как правильно оптимизировать скорость выполнения запросов? ... |
|||
:
Нравится:
Не нравится:
|
|||
01.10.2020, 10:56 |
|
Несколько Join таблицы саму на себя
|
|||
---|---|---|---|
#18+
para_bit, 1. Перевести все в InnoDb и даже лучше в xtraDb или как там оно зовется. 2. Навешать правильные ключи. 3. Объединять 1 раз с group by и having с подсчетом кол-ва атрибутов у товара .. в общем, перейти на eav выборки. как-то так. Детальней надо вспоминать .. давно с продольным хранением атрибутов на якшался.. подзабыл ужо. Кстати! Может коллективно вспомнить, обсудить и выложить в фак? Типо "штатная работа с EAV" .. там при правильной готовке запросов снижение скорости от прямых выборок из широких таблиц не превышало 2-3 раз на MySql 5.1.47 .. когда это было .. ;) ... |
|||
:
Нравится:
Не нравится:
|
|||
01.10.2020, 11:15 |
|
Несколько Join таблицы саму на себя
|
|||
---|---|---|---|
#18+
Arhat109, Спасибо за ваш ответ, 1) сейчас работает на MyIsam, насколько я понимаю выборка с этим типом шустрее 2) Индексы и ключе расставлены ... |
|||
:
Нравится:
Не нравится:
|
|||
01.10.2020, 11:50 |
|
Несколько Join таблицы саму на себя
|
|||
---|---|---|---|
#18+
para_bit, В таком разе, что Вы хатите? Раз "все есть и шустрее" .. ;) ... |
|||
:
Нравится:
Не нравится:
|
|||
01.10.2020, 12:08 |
|
Несколько Join таблицы саму на себя
|
|||
---|---|---|---|
#18+
Arhat109, где-то тут, за 2011-2013гг болтается описание того сервака, на котором всё это отрабатывалось, кажется 2 ядра Xeon по 1.9Мгц и 8 гигабайт оперативы. СУБД товаров - 500тыс строк. Атрибутов около 3-15 на товар. Средняя выборка по атрибутам в пределах 0.6сек. как-то так, возможно micsoft ещё помнит.. ;) ... |
|||
:
Нравится:
Не нравится:
|
|||
01.10.2020, 12:10 |
|
Несколько Join таблицы саму на себя
|
|||
---|---|---|---|
#18+
para_bit Необходимо получать товары по заданным атрибутам. В качестве реализации использую вот такой запрос: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29.
ЯНХНП. Запрос кривой. Запятая перед FROM, неизвестная таблица p2c, куча непонятных жойнов, в списке выбора поля, не участвующие в группировке. ... |
|||
:
Нравится:
Не нравится:
|
|||
01.10.2020, 16:44 |
|
Несколько Join таблицы саму на себя
|
|||
---|---|---|---|
#18+
paver, Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28.
спасибо, поправил запрос в этом сообщении, каждый JOIN это поиск по конкретному типу атрибута, 8 Join = 8 типов атрибутов. Про какие вы поля, какие не участвуют в группировке ... |
|||
:
Нравится:
Не нравится:
|
|||
01.10.2020, 17:45 |
|
Несколько Join таблицы саму на себя
|
|||
---|---|---|---|
#18+
para_bit Код: sql 1.
para_bit Код: sql 1.
... |
|||
:
Нравится:
Не нравится:
|
|||
01.10.2020, 23:02 |
|
Несколько Join таблицы саму на себя
|
|||
---|---|---|---|
#18+
Да, мне тоже непонятно. Если это восемь разных групп атрибутов, то атрибут не должен попадаться в разных группах, верно? Иначе это похоже на " синий или красный" + "мелкий или средний" + "гладкий или синий " ... |
|||
:
Нравится:
Не нравится:
|
|||
01.10.2020, 23:37 |
|
Несколько Join таблицы саму на себя
|
|||
---|---|---|---|
#18+
По-моему, эту задачу можно решить одним джойном, если выполняются следующие условия: - все атрибуты делятся на известное число категорий (цвет, размер, производитель) - внутри категории, атрибуты взаимоисключающие (товар не может быть зеленый и желтый одновременно) - из первых двух следует, что у товара не может быть больше атрибутов, чем категорий это также означает, что атрибуты для критерия поиска можно смешать вместе (ищем красный + маленький + китайский) Ниже я привожу пример (правда на Оракле, я с ним работаю), а тут попробую написать сохраняя синтакс ТС Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.
Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25.
... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2020, 01:47 |
|
Несколько Join таблицы саму на себя
|
|||
---|---|---|---|
#18+
para_bit Код: sql 1. 2. 3. 4.
Про какие вы поля, какие не участвуют в группировке Группируете по model, а в списке селекта используете product_id. Если между product_id и model имеется взаимно однозначное соответствие, то группировать явно лучше по полю int, а не varchar. Тогда и индекс по model не потребуется ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2020, 05:38 |
|
Несколько Join таблицы саму на себя
|
|||
---|---|---|---|
#18+
miksoft, спасибо, вы правы, атрибуты действительно не должны повторяться в рамках одного типа, моя невнимательность. Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28.
... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2020, 05:53 |
|
Несколько Join таблицы саму на себя
|
|||
---|---|---|---|
#18+
НеофитSQL, Число категорий атрибутов действительно известно, но не все атрибуты взаимоисключающие, так, например изделие может быть: Золотое, 585 пробы, иметь 2 камня Сапфир и Бриллиант, и соответственно несколько цветов камней Фиолетовый и Белый. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2020, 05:58 |
|
Несколько Join таблицы саму на себя
|
|||
---|---|---|---|
#18+
para_bit НеофитSQL, Число категорий атрибутов действительно известно, но не все атрибуты взаимоисключающие, так, например изделие может быть: Золотое, 585 пробы, иметь 2 камня Сапфир и Бриллиант, и соответственно несколько цветов камней Фиолетовый и Белый. Это можно привести к взаимоискчающим атрибутам через увеличение числа категорий (материал, проба, тип камня1, тип камня2,..), но выглядит трудоёмко. Вот ещё одна идея, которую можно попробовать за пару минут: замените все джойны на RIGHT JOIN, оставьте все остальное как было. Я сейчас не у компа, но учитывая просеивающую форму запроса, это по-моему будет то что надо.. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2020, 07:24 |
|
Несколько Join таблицы саму на себя
|
|||
---|---|---|---|
#18+
НеофитSQL замените все джойны на RIGHT JOIN ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2020, 08:12 |
|
Несколько Join таблицы саму на себя
|
|||
---|---|---|---|
#18+
НеофитSQL, Спасибо, попробовал, но не помогло, время выполнения прежнее ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2020, 08:20 |
|
Несколько Join таблицы саму на себя
|
|||
---|---|---|---|
#18+
Посоветовали пару решений на другом форуме, изложу ниже результаты по ним Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.
Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.
... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2020, 08:23 |
|
Несколько Join таблицы саму на себя
|
|||
---|---|---|---|
#18+
НеофитSQL, Все верно, примерно так как Вы и дали запрос: там на самом деле пофиг сколько типов атрибутов у товара 8 или иное число. Джойн ровно один, а вот все остальное регулируется в WHERE и HAVING Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18.
При правильно настроенных индексах запросы такого формата работают наиболее оптимальным способом. Вот, по ним и их переработке на оконные функции и предлагаю сделать очередной "фак".. ;) ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2020, 08:34 |
|
Несколько Join таблицы саму на себя
|
|||
---|---|---|---|
#18+
В третьем варианте откуда взялась таблица категорий товаров? Если она есть, то да, по ней тоже можно отсеять не нужное. Особенно, если атрибуты - категорированы и список IN() можно делить по ним. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2020, 08:49 |
|
Несколько Join таблицы саму на себя
|
|||
---|---|---|---|
#18+
Arhat109, получился вот такой запрос для 8 параметров Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27.
Время выполнения 0.9107 сек. Таблицу категории да, тоже включил ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2020, 10:02 |
|
Несколько Join таблицы саму на себя
|
|||
---|---|---|---|
#18+
para_bit, опишите словами условия в блоке HAVING там у Вас не строгое равенство почему-то. Вы ищете по ИЛИ в такой набор атрибутов ИЛИ из этой группы? ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2020, 10:59 |
|
Несколько Join таблицы саму на себя
|
|||
---|---|---|---|
#18+
Arhat109, отбираем товары, у которых: Проба 585 или 750 И Метали Золото или Серебро И размер 17 или 22 или 40 или 50 И Камень Сапфир или Бриллиант И Цвет Фиолетовый или Белый .... В рамках одной группы атрибутов может быть, как одно, так и несколько условий, искать можем, как по 585 и 750, так и просто по 585 Т.е. задаем условие поиска в каталоге товаров ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2020, 11:35 |
|
Несколько Join таблицы саму на себя
|
|||
---|---|---|---|
#18+
помоему вы фасеты хотите. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2020, 11:50 |
|
Несколько Join таблицы саму на себя
|
|||
---|---|---|---|
#18+
para_bit, Вот. Значит Вам надо считать не кол-во атрибутов золото оно ИЛИ серебро, а кол-во их категорий есть И Проба И Метали И размер И Камень И Цвет в части HAVING, а по или отбор произойдет в WHERE. Как-то так наверное: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19.
Произведение даст нуль, если хотя бы одна группа отсутствует. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2020, 11:55 |
|
Несколько Join таблицы саму на себя
|
|||
---|---|---|---|
#18+
Кстати, получилось что cntAttr Вам вообще тут не интересен, сколько их нашлось всего. Можно в SELECT воткнуть логическую функцию И то И это .. и в HAVING проверять только ее истинность. Сравните с таким же колвом параметров с другими способами .. уже интересно :) ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2020, 11:58 |
|
|
start [/forum/topic.php?fid=47&msg=40004800&tid=1828360]: |
0ms |
get settings: |
9ms |
get forum list: |
14ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
135ms |
get topic data: |
11ms |
get forum data: |
2ms |
get page messages: |
58ms |
get tp. blocked users: |
1ms |
others: | 14ms |
total: | 252ms |
0 / 0 |