简化MySQL查询,查找给定月份的重复订单?

时间:2017-06-16 18:29:11

标签: mysql

所以我有一个每月运行的脚本,查看前几个月的订单,并查看这些订单中有多少是通过前几年匹配的电子邮件地址放置的,以确定我们获得的重复业务数量新业务。

问题是数据库正在增长,业务做得越来越好,这需要很长时间。我想我需要磨练自己的技能。寻求帮助来绕过它。

现在我做一个简单的查询:

SELECT email, COUNT(orderid) as count, SUM(total) as revenue
FROM orders
WHERE date > '2017-05-01 00:00:00';

然后我只是使用PHP循环搜索这些结果,搜索上一段时间内任何匹配的电子邮件地址。

SELECT email, COUNT(orderid) as count, SUM(total) as revenue
FROM orders
WHERE date < '2017-05-01 00:00:00'
AND email = $email;

当然,我们已经到了每个月要做几千个订单的地步,而且我们已经做了几年的生意,这个过程变得非常缓慢。有没有办法将其组合成单个查询以提高性能?我查看了子查询,但它仍然会运行相同数量的查询,但仍然只是更加简洁。关于如何改进这个的任何想法?

现在我只是运行一次并将结果保存到报告数据库,所以每个月只进行一次,但我想我应该借此机会寻求帮助,看看我是否可以改进。 / p>

3 个答案:

答案 0 :(得分:0)

我认为这可能是你正在寻找的东西:

SELECT *
FROM (
    SELECT email, COUNT(orderid) as count, SUM(total) as revenue
    FROM orders
    WHERE date < '2017-05-01 00:00:00'
    GROUP BY email) as o1
INNER JOIN (
    SELECT email, COUNT(orderid) as count, SUM(total) as revenue
    FROM orders
    WHERE date >= '2017-05-01 00:00:00'
    GROUP BY email) as o2
    ON o2.email = o1.email;

你只需要正确命名你的别名,就是这样。这将为两个时段运行两个子查询,如果两个中都有匹配 - 您将得到一个结果。为了尽可能提高效率,请创建一个date是第一个密钥的索引。

另外,如果我理解正确的话,如果您只查找在最近一段时间内下订单的电子邮件,则第二个子查询甚至无法包含分组,因此您的查询可能如下所示:

SELECT o1.email, COUNT(o1.orderid) as count, SUM(o1.total) as revenue
FROM orders as o1
WHERE o1.date < '2017-05-01 00:00:00'
AND EXISTS (SELECT *
            FROM orders AS o2
            WHERE o2.email = o1.email
            AND o2.date >= '2017-05-01 00:00:00')
GROUP BY o1.email;

答案 1 :(得分:0)

这样的事情应该这样做:

SELECT 
    new_orders.email, 
    COUNT(new_orders.orderid) as count, 
    SUM(new_orders.total) as revenue
FROM 
    orders new_orders
    join (select distinct email from orders where old_orders.date <= '2017-05-01 00:00:00') old_orders on old_orders.email = new_orders.email 
WHERE
    new_orders.date > '2017-05-01 00:00:00'
GROUP BY
    new_orders.email

答案 2 :(得分:0)

您是否尝试过嵌套查询?

虽然您正在扫描相同的数据,但是将第一个结果集返回给PHP以及每个后续查询都会产生开销。

使用嵌套查询可以避免这种情况,并允许数据库进行自己的内部优化,这可能很重要。