запрос на то, что покупатели купили вместе с перечисленным товаром - PullRequest
0 голосов
/ 28 июня 2010

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

у меня есть подзапрос, но он очень медленный, занимает ~ 15 с на ~ 8 000 000 строк.

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

в этом примере я хочу перечислить все самые популярные продукты, которые пользователи купили вместе с productid 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: спасибо за ваши комментарии, ребята, вот мои ответы, они не подходятполе комментариев.

Используя EXPLAIN для вышеприведенного запроса, я получил fllowing.Обратите внимание, что у меня нет никаких индексов в таблице (кроме первичного ключа в 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                                  |
+----+--------------------+----------+------+---------------+------+---------+------+------+----------------------------------------------+

Ответы [ 3 ]

1 голос
/ 28 июня 2010

Помимо обеспечения наличия подходящих индексов для 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. Следовательно, соединение было на порядок быстрее.

1 голос
/ 28 июня 2010

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

0 голосов
/ 28 июня 2010

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

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

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

...