繁体   English   中英

如何优化下面使用三个级别的select语句的查询?

[英]How can I optimize the query below which uses three levels of select statements?

如何优化以下查询:

我有两个表,“ calendar_table”和“ consumption”,在这里,我使用此查询来计算每年的每月消费。

日历表具有2005-2009年的日,月和年,并且消耗表具有按月计费周期的计费消耗数据。 该查询将计算每张账单的天数,并用于查找每个月的消费量。

SELECT id,
        date_from as bill_start_date,
        theYear as Year,
        MONTHNAME(STR_TO_DATE(theMonth, '%m')) as month, 
        sum(DaysOnBill),
        TotalDaysInTheMonth,
        sum(perDayConsumption *  DaysOnBill) as EstimatedConsumption 
    FROM
    ( 
     SELECT
        id,
        date_from,
        theYear,
        theMonth,  # use theMonth for displaying the month as a number
        COUNT(*) AS DaysOnBill,
        TotalDaysInTheMonth, 
        perDayConsumption
    FROM
        (
        SELECT
            c.id,
            c.date_from as date_from,
            ct.dt,
            y AS theYear,
            month AS theMonth,
            DAY(LAST_DAY(ct.dt)) as TotalDaysInTheMonth,
            perDayConsumption
        FROM
            consumption AS c
            INNER JOIN
            calendar_table AS ct
                ON ct.dt >= c.date_from
                    AND ct.dt<= c.date_to
        ) AS allDates
    GROUP BY
        id,
        date_from,
        theYear,
        theMonth ) AS estimates
GROUP BY
        id,
        theYear,
        theMonth;       

完成大约一百万条记录大约需要1000秒。 可以做些什么使它更快吗?

该查询有点可疑,假装先进行一个分组,然后再与另一个分组进行构建,实际上并非如此。

首先,该法案一整天都加入进来。 然后,我们按帐单加上月份和年份进行分组,从而每月查看一次数据。 可以一次性完成此操作,但是查询首先要加入,然后再将结果用作派生表进行汇总。 最后,再次获取结果并建立“另一个”组,该组实际上与以前相同(帐单加月和年),并完成了一些伪聚合(例如sum(perDayConsumption * DaysOnBill)与perDayConsumption * DaysOnBill,因为SUM仅在此处汇总一条记录)。

可以简单地写成:

SELECT
  c.id,
  c.date_from as bill_start_date,
  ct.y AS Year,
  MONTHNAME(STR_TO_DATE(ct.month, '%m')) as month,
  COUNT(*) AS DaysOnBill,
  DAY(LAST_DAY(ct.dt)) as TotalDaysInTheMonth,
  SUM(c.perDayConsumption) as EstimatedConsumption
FROM consumption AS c
INNER JOIN calendar_table AS ct ON ct.dt BETWEEN c.date_from AND c.date_to
GROUP BY
  c.id,
  ct.y,
  ct.month;

我不知道这是否会更快,或者MySQL的优化器是否看不到您的查询本身并将其归结为这种情况。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM