我最近发表了一篇文章,内容基本上可以归结为同一个问题,但使用了不同的数据库技术(这意味着找到的解决方案——其中涉及使用ROW_NUMBER()——在这里不适用)。
假设我在MySQL数据库中有一个名为“Customers”的表。我还有一个名为“Orders”的表,每个表都包含一个“CustomerID”。我想做的是,为每个“客户”生成一个总结,说明他们下了多少订单,以及他们的第一个和最后一个“订单”是什么时候发生的。
我一直在使用的查询如下:
SELECT
Customer.CustomerID,
Customer.Name,
COUNT(Orders.OrderID) AS Orders,
MIN(Order.Timestamp) AS OldestOrder,
MAX(Orders.Timestamp) AS NewestOrder
FROM Orders
INNER JOIN Customerts ON Orders.OrderID = Customers.CustomerID
GROUP BY Orders.CustomerID
这个查询得到的正是我想要的,但是在一个包含几十万个订单的数据库中,执行它可能需要2-3秒。
通过在“Orders”表中添加包含“CustomerID”和“Timestamp”的索引,这一次可以缩短到大约1秒或更短,但这仍然是不可接受的。执行此查询的客户列表通常相对较小,因此通过执行单个查询以获取数据的每个客户的循环是一个更快的选择,但这要复杂得多。
是否还有其他索引机会我没有看到,或者这个查询需要以完全不同的方式运行?如果我可以使用MSSQL的ROW_NUMBER()功能,那么这个查询可以非常快速地工作。。。
提前谢谢:)!
编辑1:解释精选节目:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE Customers ALL PRIMARY NULL NULL NULL 10 Using temporary; Using filesort
1 SIMPLE Orders ref CustomerID_2 CustomerID_2 4 Customers.CustomerID 4038 Using where
最佳答案
SELECT
Customers.CustomerID,
Customers.Name,
COUNT(Orders.OrderID) AS Orders,
MIN(Orders.Timestamp) AS OldestOrder,
MAX(Orders.Timestamp) AS NewestOrder
FROM Customers
INNER JOIN Orders ON Orders.CustomerID= Customers.CustomerID
GROUP BY Customers.CustomerID