2015-04-28 80 views
2

我想从MySQL获取一些用户统计信息。喜欢的东西:如何优化多个子查询?

  • 10%的用户购买了百事可乐
  • 20%是女人
  • 40%是在美国

的第一步是获取所有用户的列表已经从百事买了东西制造商。

此查询在1秒内​​运行良好,并返回用户标识列表。

SELECT DISTINCT idUser FROM checkout_item INNER JOIN (
    SELECT id FROM product WHERE manufacturer = "pepsi" 
) AS chkItem ON chkItem.id = checkout_item.idProduct 

现在我使用此列表获取信息。刚刚在上面添加了一个查询:

SELECT 
    name, gender 
FROM users INNER JOIN(

    SELECT DISTINCT idUser FROM checkout_item INNER JOIN ( // 
    SELECT id FROM product WHERE manufacturer = "pepsi" // same query above 
) AS chkItem ON chkItem.id = checkout_item.idProduct  // 

) AS usr ON usr.idUser = users.id 

此查询正在工作,但它需要23秒。有什么办法可以优化吗?

也许使用WHEREs,JOINs或更改mysql RAM配置?

+2

您的表格是否编入索引? – vaso123

+0

谢谢@lolka_bolka,我在NAME和GENDER字段创建了索引,现在需要2秒。 – anderlaini

+1

我很难相信名称和性别的索引会有帮助,因为它们不包含在任何过滤参数中。查询是否发生了与您发布的查询不同的查询? –

回答

1

这是对第一个查询的重写。也许你可以弄清楚其余的。

SELECT DISTINCT idUser 
      FROM checkout_item i 
      JOIN product p 
      ON p.id = i.idproduct 
      WHERE p.manufacturer = 'pepsi' 
0

尝试这种情况: 选择名称,从checkout_item℃的内部(从产品选择ID WHERE制造商= “百事可乐”)JOIN P于p.id = C.idProduct INNER JOIN用户U ON C.性别 ID用户= u.Id

还可考虑在指数上checkout_item场idProduct的

0

下面应该给你idUsers的总数,idUsers谁是女性总数(很明显,我不知道你用什么作为性别的标志,所以我刚刚使用'f')。

SELECT COUNT(DISTINCT idUser) AS Total, 
    COUNT(DISTINCT CASE WHEN gender = 'f' then idUser else null end) AS women 
FROM checkout_item ci 
    inner join product p 
     on p.id=ci.idProduct 
WHERE p.manufacturer = 'pepsi' 

从那里它应该是基本的数学得到你需要的数字。

通常我不会推荐使用'DISTINCT',但是不太了解您的数据,这是快速和肮脏的方式,使一些工作。

希望有帮助!