我的mySQL查询花了太多时间(大约12秒) - 任何建议

时间:2017-01-02 20:31:20

标签: mysql aggregate-functions query-performance correlated-subquery

我的mySQL查询有问题,因为该表有大约70,000条记录需要太多时间(约12秒)

这是我的查询:

SELECT  DATE(`orders`.`date`) AS `dater`,
        COUNT(*) AS `amount`,
        ( SELECT SUM(`amount`) FROM `payment`
              WHERE DATE(`dater`)=DATE(`payment`.`posted_date`)
        ) AS `charge`
    FROM `orders`
    GROUP BY `dater`
    ORDER BY `dater` DESC
    LIMIT 0,10

如您所见,有2张桌子 表:订单 这是订单表,我们有1个主栏:日期(我们这里需要计算每天的订单数)

样品:

--------------------
date        | id
--------------------
01-01-2017  | 1
--------------------
01-01-2017  | 2
--------------------
01-02-2017  | 3
--------------------
  1. 表:付款: 这是付款表,我们有2个主要栏目:posted_date,金额(我们需要在这里得到每天金额字段的总和)
  2. 样品:

    --------------------
    posted_date | amount
    --------------------
    01-01-2017  | 100
    --------------------
    01-01-2017  | 50
    --------------------
    01-02-2017  | 200
    --------------------
    

    所以结果应该是[日期,金额,费用]

    确保在更短的时间内完成,因为这12秒是不可能的:D

    我看到问题出现在这个内部的SELECT上:

    (SELECT SUM(`amount`) FROM `payment`
        WHERE DATE(`dater`)=DATE(`payment`.`posted_date`)
    ) AS `charge`
    

    有关如何避免在SELECT查询中进行SELECT的任何建议?

1 个答案:

答案 0 :(得分:1)

您有一个相关的子查询。 MySQL的查询计划程序以一种天真的方式处理它们,以礼貌地表达它。

重构您的查询以改为使用连接。您的相关子查询看起来像是一个可连接的查询。

           SELECT SUM(amount) charge,
                  DATE(posted_date) posted_date
             FROM payment
            GROUP BY DATE(posted_date)

每天从付款表中获取一行。

接下来,您需要从订单表中获得类似的结果。

         SELECT DATE(date) AS dater,
                COUNT(*) AS amount
           FROM orders
          GROUP BY DATE(date)

然后,加入这两个

SELECT a.dater, a.amount, b.charge
  FROM (
         SELECT DATE(date) AS dater,
                COUNT(*) AS amount
           FROM orders
          GROUP BY DATE(date)
       ) a
  LEFT JOIN (
           SELECT SUM(amount) charge,
                  DATE(posted_date) posted_date
             FROM payment
            GROUP BY DATE(posted_date)
       ) b ON a.dater = b.posted_date
 ORDER BY a.dater DESC
 LIMIT 0,10

在此处加入两个子查询是必要的,因为按日期需要两个聚合来使联接起作用。