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

Php 提高使用COUNT、MIN和MAX的查询的效率,php,mysql,Php,Mysql,我最近发布了关于本质上可以归结为同一问题但使用不同数据库技术的内容(这意味着找到的解决方案——涉及使用ROW_NUMBER()——在这里不适用) 假设我在MySQL数据库中有一个名为“Customers”的表。我还有一个名为“Orders”的表,每个表都包含一个“CustomerID”。我想做的是,为每个“客户”生成一个总结,说明他们已经下了多少订单,以及他们的第一个和最后一个“订单”是何时发生的 我为此使用的查询如下: SELECT Customer.CustomerID, C

我最近发布了关于本质上可以归结为同一问题但使用不同数据库技术的内容(这意味着找到的解决方案——涉及使用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

看来答案就在我面前!将我在OP中提到的包含“CustomerID”和“Timestamp”的索引替换为包含“OrderID”的索引,将查询时间缩短到0.07秒左右!然后,如Jignesh Patel的回答中所述,通过使用“客户”表作为焦点,这一比例进一步降低了约50%。

Customer.Name
添加到
group by
子句中,然后使用
explain select…
至少获得执行计划,有关查询性能的问题始终需要为所有相关表创建表语句并进行解释。此外,你似乎在问两个不同的问题,因为我看不出MSSQL的行数选项能带来什么好处。@juergend我已经尽我所能添加了一个解释。@草莓这个查询是真实查询的简化版本,我没有为真实数据创建任何上下文(客户和订单)完全不同。我希望在更高的层次上解决这个问题。不幸的是,我只能处理更多的尘世问题。你能补充一些澄清,而不是仅仅发布代码吗?这是解决这个问题的一个有趣的方法!它确实比最初的查询快,但遗憾的是仍然太慢了。此外,我希望在更高的层次上解决这个问题,这样它就可以广泛应用于多个查询,我不确定这种特定的解决方案是否真的能解决这个问题。需要多少时间?是否在两个表中的CustomerID字段上都创建了索引?大约0.5秒,在这两个表中都有一个索引。您可以使用称为物化视图的技术,mysql没有的特定工具。但想法是创建表,若并没有太多的更新/插入操作,ant会在每次更新时重新计算数据。或者按时间间隔刷新数据(如果您的要求可以接受)。
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