0

我正在尝试优化一个我无法理解的非常古老的查询。我想要归档的结果是,我想在网上商店向访问者推荐其他客户感兴趣的东西,即他们与访问者正在查看的产品一起购买的其他东西。

我有一个子查询,但它慢,在 ~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-field 上的主键除外),我想修改查询以从索引中受益并将索引放在正确的键上。

+----+--------------------+----------+------+---------------+------+---------+------+------+----------------------------------------------+
| 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                                  |
+----+--------------------+----------+------+---------------+------+---------+------+------+----------------------------------------------+
4

3 回答 3

1

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

于 2010-06-28T11:11:54.290 回答
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: SIMPLEEXPLAIN,而子查询方法吐出一个可怕的性能DEPENDENT SUBQUERY。因此,连接速度要快一个数量级以上。

于 2010-06-28T11:26:58.200 回答
0

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

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

索引是一个单独的已排序文件,仅包含您对排序感兴趣的字段。因此创建索引可以节省大量时间!

于 2010-06-28T11:19:34.660 回答