查询客户与所列产品一起购买的产品

时间:2010-06-28 10:58:53

标签: mysql subquery webshop

我正在尝试优化一个我无法解决的非常古老的查询。我希望存档的结果是,我想在网上商店推荐其他客户对其感兴趣的访问者,即他们与访问者正在查看的产品一起购买的其他内容。

我有一个子查询,但是非常慢,在~8 000 000行上需要大约15秒。

布局是放在用户购物篮中的所有产品都保存在表wsBasket中,并由basketid分隔(在另一个表中与成员关联)。

在这个例子中,我想列出用户与productid 427一起购买的所有最受欢迎的产品,但不列出productid 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我得到了结果。请注意,我在表上没有任何索引(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 个答案:

答案 0 :(得分:1)

要添加两个明显的索引:一个在basketid上,另一个在productid上:然后重试查询和一个新的EXPLAIN以查看正在使用的索引

答案 1 :(得分:1)

除了确保productidbasketid上存在合适的索引之外,通常还可以将查询结构化为简单连接而不是子查询,尤其是在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 。因此,加入速度提高了一个数量级。

答案 2 :(得分:0)

您主要用于在此查询中搜索的两个字段是productid和basketid。

当您搜索productid等于427的记录时,数据库不知道在哪里可以找到此记录。它甚至不知道如果找到一个匹配,那么就不会有另一个匹配的匹配,所以它必须查看整个表,可能有数千个记录。

索引是一个单独的文件,它被排序,并且只包含您有兴趣排序的字段。所以创建一个索引可以节省大量的时间!