农业-大量数据在数据库中做AVG如何优化

如果是直接查询呢?

设备每个分区3s回传一次数据

一个设备有三个分区

一分钟需要回传 3 * 20 = 60次

一个小时 回传 60*60 = 3600次

一天回传 3600 * 24 = 86400次

我如果想计算以天为单位的气温数据,需要聚合8w条数据

进行优化

一分钟60次,记录60分钟的数据

一小时 对 60分钟的数据进行统计,一共60个

一天 对24小时的数据进行统计,一共24个

sql测试

在一天的数据量8640条数据中 按每小时进行聚合统计,是一个很大的开销,但是可以接受

SELECT
    DATE_FORMAT(created_at, "%Y-%m-%d %H : %i") AS time_minute,
    AVG(temperature) AS avg_temperature,
    AVG(humidity) AS avg_humidity
FROM
    agriculture_cybe.device_hearts
WHERE
    device_id = 315
GROUP BY
     DATE_FORMAT(created_at, "%Y-%m-%d %H :%i") 
ORDER BY
    time_minute DESC;

执行耗时3s

查看操作行数

那么如果是 月和年呢?
执行时间19s

查看操作行数

需要检索68w条 这是相当大的数据

最关键的是,这个只是检索一个设备的气温开销,而我们将来可能会有300+以上的设备,这更是一笔很大的开销

如何优化呢?

 分支思想

解决上面这种求平均数的方法可以使用分治的思想

1 2 3 4 5 6 7 8 9 求平均值

3/2      7/2       11/2       15/2         9

第一次计算

5/2        13/2         9

第三次计算

9/2        9

接下来需要加权计算

9/2*8/9  +  9*1/9

3.96+1 = 4.96

误差只有0.04完全可以接受

但是项目中没有使用加权计算这种方式,这种方式运算太复杂了

需要求出总数进行加权

我们使用的方法是

和前一个数据一起做统计,这样可以解决数据尖刺问题

数据尖刺

假设2:01的温度突然升高

此时统计的数据就是增高后的数据,并不是平均值

那么会出现下面的情况

小时图,突然飙高,但是10分钟之后又回复了正常

那是因为此时正好进行小时级别的平均值的运算

分钟表中就这一条异常数据,所以对这一条异常数据算平均数 那平均数就是异常数据本身

如何解决呢?

1. 加权

2. 和前面的数据一起计算平均值

计算分钟平均值的时候,不止计算当前分钟的平均值,而是计算一个区间

1:58到2:01 这三分钟内的平均值,这样就可以解决尖刺问题了

索引

所以需要做优化,首先给时间字段加上索引 (实测 不一定走索引,交给执行引擎自己选择索引)

走时间索引之后的时间

避免大量数据做聚合统计

一开始是直接统计2023-2024年的数据

现在我是先统计月度数据,再将月度数据统计为 年度数据

将where 的范围减少,降低数据库做聚合的压力


SELECT
    DATE_FORMAT(created_at, "%Y-%m-%d %H:%i") AS time_minute,
    AVG(temperature) AS avg_temperature,
    AVG(humidity) AS avg_humidity
FROM
    agriculture_cybe.device_hearts
WHERE
    device_id = 9 AND
    created_at >= '2024-04-25 08:56' AND
    created_at <= '2024-04-25 10:26'
GROUP BY
    time_minute
ORDER BY
    time_minute ASC;

执行时间缩短为0s

将数据存入分钟记录表

随后将分钟记录表中的数据,计算极值,和平均值,存入hour表

hour表中才真实存在了极值数据

char表

现在已经将年月日  最高最低平均 气温数据提取出来

但是目前响应时间还是有点慢

因为需要进行3次查表

查询平均  最高  最低气温的表记录 总共三次

而且需要将他们序列化为json格式,又是一批不小的开销

所以我使用定时任务,提前将表的数据解析到数据库里面

  • 20
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值