提高使用COUNT,MIN和MAX的查询的效率

时间:2016-05-20 10:58:25

标签: php mysql

我最近发布的内容基本上归结为相同的问题,但使用不同的数据库技术(意味着找到的解决方案 - 涉及使用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秒。

通过向包含“CustomerID”和“Timestamp”的“Orders”表添加索引,此时间缩短到大约1秒或更短,但这仍然是不可接受的。此查询将被执行的客户列表通常相对较小,因此通过执行单个查询以获取数据的每个客户的循环是一个更快的选项,但这更加混乱。

我还没有看到进一步的索引机会,或者这个查询是否需要以完全不同的方式运行?如果我拥有MSSQL的ROW_NUMBER()功能,那么这个查询可以非常快速地运行......

提前致谢:)!

编辑#1:EXPLAIN SELECT显示:

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

2 个答案:

答案 0 :(得分:1)

viewController

答案 1 :(得分:0)

看来答案就在我面前!将我在OP中提到的索引(包括“CustomerID”和“Timestamp”)替换为包含“OrderID”的索引,将查询降低到大约0.07秒!根据Jignesh Patel的回答,使用“客户”表作为焦点,这进一步减少了大约50%。