所以我有一个每月运行的脚本,查看前几个月的订单,并查看这些订单中有多少是通过前几年匹配的电子邮件地址放置的,以确定我们获得的重复业务数量新业务。
问题是数据库正在增长,业务做得越来越好,这需要很长时间。我想我需要磨练自己的技能。寻求帮助来绕过它。
现在我做一个简单的查询:
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>
答案 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以及每个后续查询都会产生开销。
使用嵌套查询可以避免这种情况,并允许数据库进行自己的内部优化,这可能很重要。