从包含多行的表中加入一行

时间:2011-12-14 08:26:51

标签: mysql optimization count query-optimization

这是关于mysql中的查询的问题。举个例子,让我们使用一个追踪汽车销售的系统。有salespersons的表格,sales的表格和连接两者的表格。大多数情况下,每次销售只有一个人与之相关。但有时多人与销售有关。

Table sales
id | carId | date
---+-------+-----------
1  | 2     | 11-01-2011
2  | 8     | 11-02-2011
3  | 5     | 11-05-2011

Table link
personId | saleId
---------+-------
2        | 1 
2        | 2 
1        | 3
2        | 3

Table salesperson
id | name  | age
---+-------+----
1  | Barry | 25
2  | Sara  | 32

要检索数据,我想在网页中显示每笔销售的信息。但是当多个人与销售相关联时,它就成了问题。我已经尝试在我的代码中应用下面的查询,之后PHP处理多个人与一个销售相关联的例外情况,但由于销售表的长度,下面的查询需要花费太多时间来运行:

SELECT count(personId) as amount, carId, date
FROM link 
JOIN salesperson ON link.personId = salesperson.id  
JOIN sales ON sales.id = link.saleId
GROUP BY link.saleId

是否可以使用更高效的查询?顺便说一下表的索引已经完成了。

5 个答案:

答案 0 :(得分:1)

然后就是:

SELECT STRAIGHT_JOIN
    amount, carId, date
FROM (
    SELECT saleId, count(*) as amount
    FROM link
    GROUP BY saleId
    ORDER BY NULL) as amounts
JOIN sales ON sales.id = amounts.saleId;

答案 1 :(得分:0)

您是否为表格设置了正确的索引?我不知道你的桌子有多大,但我无法想象它应该是一个很大的问题。

另外,您试图从查询中获得什么结果?您似乎想要获得所有销售额,然后计算涉及多少销售人员?

答案 2 :(得分:0)

你的查询看起来没问题,但你的小组有点奇怪...
尝试按所有非聚合列进行分组的标准方法,如下所示:

SELECT carId, date, name, age, count(personId) as amount
FROM link 
JOIN salesperson ON salesperson.id = link.personId
JOIN sales ON sales.id = link.saleId
GROUP BY 1,2,3,4;

答案 3 :(得分:0)

我认为问题可能是您使用链接表作为基表,并且查询的数据库优化不好。 尝试:

SELECT count(sp.personId) as amount, s.carId as carId, s.date as date, sp.name as name, sp.age as age  
FROM sales as s
JOIN link as l ON s.id = l.saleId
JOIN salesperson as sp ON l.personId = sp.id  
ORDER BY l.saleId

答案 4 :(得分:0)

如果您关注性能方面,请避免使用Joins,尤其是在mysql中。 阅读本文演示了有效的编码技术 http://phpadvent.org/2011/a-stitch-in-time-saves-nine-by-paul-jones

针对您在第一次查询中的问题,选择销售ID 在第二个查询中从链接表中选择personID 在第三个查询中选择从人员表中选择所有人

如文章中所提到的,在传递查询时使用IN子句。它在编码中看起来很长,但比在15k +行上使用连接

更有效