Запрос того, что покупатели купили вместе с перечисленным продуктом

StackOverflow https://stackoverflow.com/questions/3131759

  •  01-10-2019
  •  | 
  •  

Вопрос

Я пытаюсь получить оптимизировать очень старый запрос, который я не могу обернуть голову. Результатом, что я хочу архивировать, так это то, что я хочу порекомендовать посетителей в веб-магазине, какие другие клиенты проявили интерес, то есть что еще они купили вместе с продуктом, на котором смотрит посетитель.

У меня есть подзапрос, но это очень Медленно, занимает ~ 15-е годы на ~ 8 000 000 строк.

Макет заключается в том, что все продукты, которые помещаются в корзину пользователей, хранятся в таблице wsBasket и разделены basketid (который в другой таблице связан с членом).

В этом примере я хочу перечислить все самые популярные продукты, которые пользователи купили вместе с ProductiDID 427, но не перечислите саму продукцию 427.

SELECT productid, SUM(quantity) AS qty 
FROM wsBasket 
WHERE basketid IN 
    (SELECT basketid 
     FROM wsBasket 
     WHERE productid=427) AND productid!=427 
GROUP by productid 
ORDER BY qty 
DESC LIMIT 0,4;

Любая помощь высоко ценится! Надеюсь, это имеет смысл вообще хотя бы кого-то :)

 

Обновление 1:Спасибо за ваши комментарии, ребята, вот мои ответы, они не вписывались в комментарии-поле.

Использование объяснения на вышеуказанном запросе я получил пленку. Обратите внимание, у меня нет никаких индексов на столе (за исключением первичного ключа на id-поле), я хочу изменить запрос, чтобы извлечь выгоду из индексов и размещать индексы на правильные клавиши.

+----+--------------------+----------+------+---------------+------+---------+------+------+----------------------------------------------+
| id | select_type        | table    | type | possible_keys | key  | key_len | ref  | rows | Extra                                        |
+----+--------------------+----------+------+---------------+------+---------+------+------+----------------------------------------------+
|  1 | PRIMARY            | wsBasket | ALL  | NULL          | NULL | NULL    | NULL | 2821 | Using where; Using temporary; Using filesort |
|  2 | DEPENDENT SUBQUERY | wsBasket | ALL  | NULL          | NULL | NULL    | NULL | 2821 | Using where                                  |
+----+--------------------+----------+------+---------------+------+---------+------+------+----------------------------------------------+
Это было полезно?

Решение

Две очевидные индексы для добавления: один на баскетсид и секунду по продуктам: затем повторите попытку запроса и новое объяснение, чтобы увидеть, что индексы используются

Другие советы

А также обеспечение того, чтобы подходящие индексы существуют на productid а также basketid, вы часто пользуетесь структурированием вашего запроса как простого присоединения, а не подзапроса, особенно в MySQL.

SELECT b1.productid, SUM(b1.quantity) AS qty
FROM wsBasket AS b0
JOIN wsBasket AS b1 ON b1.basketid=b0.basketid
WHERE b0.productid=427 AND b1.productid<>427
GROUP BY b1.productid
ORDER BY qty DESC
LIMIT 4

Для меня, по возможному набору данных, присоединение привело к двум select_type: SIMPLE строки в EXPLAIN вывод, в то время как метод подзапроса выпадает ужасно-для производительности DEPENDENT SUBQUERY. Отказ Следовательно, присоединение было хорошо за порядок быстрее.

Две поля, которые вы в основном используете для поиска в этом запросе, являются продуктами и базистыми.

Когда вы ищете записи, имеющие ProductiD, равную 427, база данных не имеет подсказки, где можно найти эту запись. Это даже не знает, что если он найдет одно соответствие, что не будет другого совпадения, поэтому он должен просмотреть всю таблицу, потенциально тысячи записей.

Индекс - это отдельный файл, который сортируется, и содержит только поле / с, которым вы заинтересованы в сортировке. Таким образом, создание индекса экономит огромное количество времени!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top