MySQL - 获取前一行数据时查询速度慢

标签 mysql

我的查询需要 0.04 秒才能加载

SELECT sg.Name AS 'Customer Name', 
m.meter_id AS 'Serial No', 
DATE_FORMAT(datetime, '%Y/%m/%d') AS Date,  
MAX(wh_total) AS Present
FROM meter_data m 
INNER JOIN enrollment e 
ON e.Meter_Id = m.meter_id AND e.Status = 1 
INNER JOIN company_subgroup sg 
ON sg.Id = e.Subgroup_Id 
INNER JOIN company_group g 
ON g.Id = sg.Group_Id 
WHERE date(dateTime) BETWEEN '2018/06/01' AND '2018/06/30' 
AND m.meter_id = '12345' 
AND m.wh_total < 1000000000 
GROUP BY date(datetime)

但如果我添加此“上一个”选择列,则执行大约需要 20 秒。

SELECT sg.Name AS 'Customer Name', 
m.meter_id AS 'Serial No', 
DATE_FORMAT(datetime, '%Y/%m/%d') AS Date, 
// THIS (main issue)
COALESCE((SELECT MAX(wh_total) FROM meter_data WHERE date(dateTime) < date(m.dateTime) AND meter_id = '12345' 
AND wh_total < 1000000000 GROUP BY date(dateTime) ORDER BY date(dateTime) DESC LIMIT 1),0) AS Previous,
//
MAX(wh_total) AS Present,
// THIS (But I guess this does not affect the query that much since it only substract the two columns) 
ROUND(MAX(wh_total) - MIN((SELECT Previous)),2) AS Consumption 
//
FROM meter_data m 
INNER JOIN enrollment e 
ON e.Meter_Id = m.meter_id AND e.Status = 1 
INNER JOIN company_subgroup sg 
ON sg.Id = e.Subgroup_Id 
INNER JOIN company_group g 
ON g.Id = sg.Group_Id 
WHERE date(dateTime) BETWEEN '2018/06/01' AND '2018/06/30' 
AND m.meter_id = '12345' 
AND m.wh_total < 1000000000 
GROUP BY date(datetime)

基本上,前一列获取前一行的数据。查询看起来像这样:

Customer Name | Serial No | Date       | Previous | Present | Consumption
ABC           | 12345     | 06/01/2018 | 0        | 1       | 1
ABC           | 12345     | 06/02/2018 | 1        | 3       | 2
ABC           | 12345     | 06/03/2018 | 3        | 8       | 5 
ABC           | 12345     | 06/04/2018 | 8        | 10      | 2 

我尝试使用 LAG(column) 来获取前一行数据,不幸的是 MySQL 版本是 5.6。有什么办法可以优化这个查询吗?

最佳答案

试试这个

SELECT sg.Name AS 'Customer Name', 
        m.meter_id AS 'Serial No', 
        DATE_FORMAT(datetime, '%Y/%m/%d') AS Date, 
        COALESCE(mx.max_total,0) AS Previous,
        MAX(wh_total) AS Present,
        ROUND(MAX(wh_total) - MIN((mx.max_total)),2) AS Consumption 
FROM meter_data m 
        INNER JOIN enrollment e ON e.Meter_Id = m.meter_id AND e.Status = 1 
        INNER JOIN company_subgroup sg ON sg.Id = e.Subgroup_Id 
        INNER JOIN company_group g ON g.Id = sg.Group_Id 
        LEFT JOIN (SELECT date(dateTime) as dt,  MAX(wh_total) max_total
                    FROM meter_data 
                    WHERE meter_id = '12345' AND wh_total < 1000000000 
                    GROUP BY date(dateTime)) mx on mx.dt < date(m.dateTime)
WHERE date(m.dateTime) BETWEEN '2018/06/01' AND '2018/06/30' 
AND m.meter_id = '12345' 
AND m.wh_total < 1000000000 
GROUP BY date(m.datetime)

注意:如果该内联返回多于一行,则通过添加更多条件来限制该行

关于MySQL - 获取前一行数据时查询速度慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51166608/

相关文章:

php - MYSQL 使用 SUM() 选择查询

php - 是否可以使用 Webpack、Sass、PHP 和 MySQL 来运行 Angular?

php - MySQL PHP 未将完整文件存储到 BLOB

SQL SELECT DISTINCT 和 GROUP BY 问题

java - 如何在 Spring JPA for MySQL 中为 @Id @GeneratedValue 设置初始值?

c# - 无法通过 ASP.NET Web 应用程序将数据插入 MySQL 表

mysql - 删除 MySQL 中除 One 之外的所有重复行?

mysql - Rails 子查询连接

java - 来自 Class.forName 的 ClassNotFoundException ("com.mysql.jdbc.Driver");

MySQL COUNT 未提供正确的结果