[英]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.