一个处理数据的需求,目前已经实现出来了,测试提出性能太低,所以请教一下,看看有没有比较好的处理实现方式,目前实现 sql 处理一部分,代码处理一部分
环境:Java1.8 Mysql 8
type | value | date |
---|---|---|
1 | 10.111 | 2023-03-21 01:00:00 |
2 | 19.111 | 2023-03-21 01:00:00 |
2 | 11.111 | 2023-03-21 02:00:00 |
3 | 12.111 | 2023-03-21 02:00:00 |
1 | 13.111 | 2023-03-22 11:00:00 |
1 | 14.111 | 2023-03-22 12:00:00 |
1 | 15.111 | 2023-03-23 11:00:00 |
一张数据库表,如上, 用户根据某种类型添加数据,type 类型固定的 1-3,按日期插入数据,日期会重复因为是用户手动选择;
目标需求:按日期(yyyy-MM-dd)分组+倒序,每个类型查出最新的一条;并统计每个类型有多少条,
如上表数据,最终预期输出为:count(是这个日期分组下,这个类型的条数)
{
"2023-03-21": [{
"type": "1",
"value": "10.111",
"date": "2023-03-21 01:00:00",
"count": 1
}, {
"type": "2",
"value": "11.111",
"date": "2023-03-21 02:00:00",
"count": 2
},
{
"type": "3",
"value": "12.111",
"date": "2023-03-21 02:00:00",
"count": 1
}
],
"2023-03-22": [{
"type": "1",
"value": "14.111",
"date": "2023-03-22 12:00:00",
"count": 1
}],
"2023-03-23": [{
"type": "1",
"value": "15.111",
"date": "2023-03-23 11:00:00",
"count": 1
}]
}
ps: 上述需求是接口里 1/5 的功能,还有后续处理
Ps: 代码简洁,支持使用第三方库
1
6a82aa9bfe 2023-03-28 11:10:00 +08:00 via Android
问问万能的 chatgpt?
|
2
dqzcwxb 2023-03-28 11:19:05 +08:00
你的需求是:将数据分组 count 且需要组名
实现方案有两个: 1,用 sql 分别实现分组统计,分组组名 性能优化点就是添加有效索引和并行查询; 2,用 sql 查询出所有数据然后用 Stream groupby 做分组统计,性能优化就是开启 parallelStream 和加机器配置; |
3
godleon OP @dqzcwxb 我现在就是 sql 分组,还遇到个问题就是分组的时候 再加 desc 分组就不会倒序了,然后又加子查询 用 max 取日期值找最新的,count 就得在分,因为我上面是 demo ,真实场景下我查出来的东西近 10W 条 40+个字段,我决定纯用代码处理试试
|
4
acctv2 2023-03-28 11:56:02 +08:00 via Android
explain 看看?
|
5
gjp0609 2023-03-28 12:25:46 +08:00
sql 开窗函数应该可以实现吧
|
6
liprais 2023-03-28 12:29:20 +08:00
mysql 8 直接 rank() over ( partition by )这种解决完事
|
7
Ikarosx 2023-03-28 14:09:12 +08:00
mark 一下,看看有没有更好的方式
```sql SELECT DISTINCT DATE_FORMAT( DATE, '%Y-%m-%d' ) day, type, COUNT(*) OVER ( PARTITION BY DATE_FORMAT( DATE, '%Y-%m-%d' ), type ) count, FIRST_VALUE( DATE ) OVER ( PARTITION BY DATE_FORMAT( DATE, '%Y-%m-%d' ), type ORDER BY DATE DESC ) date, FIRST_VALUE( VALUE ) OVER ( PARTITION BY DATE_FORMAT( DATE, '%Y-%m-%d' ), type ORDER BY DATE DESC ) value FROM test ``` |
8
wenxueywx 2023-03-28 17:08:54 +08:00
期望的数据有问题吧,3-22 的 type 为 1 的数据有两条。如果确认的话窗口函数确实可以解决
|
10
Derek8863 2023-03-28 19:44:40 +08:00
建议用 ck 或者 presto 做计算引擎
|
11
dode 2023-03-28 20:33:44 +08:00 via Android
建议最新一条单独纯一个表🐇
|
12
dode 2023-03-28 20:34:53 +08:00 via Android
如果只有 3 种,就分别查询,再联合一下吧
|
13
crazyweeds 2023-03-28 21:14:05 +08:00
如果你返回条目数小的情况下,可以尝试代码层面多线程。SQL 拿到最新的日期列表,然后用日期作为参数,多线程循环执行 SQL 。
|
14
why1001 2023-03-28 21:23:56 +08:00
如果项目中引入了 guava 可以看下 Multimap 类型
|
15
noparking188 2023-03-28 21:44:08 +08:00
最好补充以下信息,决定方案选择
1. 数据更新频率; 2. 预估数据总量; 3. 数据查询频率; 4. 查询响应要求; Java 后端里写业务逻辑对 MySQL 中的数据做复杂**分析**处理?也许提供业务场景上下文更清晰一点 |
16
14104chk 2023-03-28 23:14:22 +08:00
可以用一张统计表,修改的时候,把当前日期的统计数据更新
|
17
luzemin 2023-03-28 23:34:48 +08:00
同意楼上
要想让读路径短一些,那就让写路径长一些。 在写入的时候,把需要的结果单独更新到某个表 /位置。 |
18
wenxueywx 2023-03-29 11:29:30 +08:00
@godleon 特意用 mysql8.0 试了下纯 sql 的方法
CREATE TABLE `t01` ( `id` int NOT NULL AUTO_INCREMENT, `type` int DEFAULT NULL, `value` double DEFAULT NULL, `date` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB ; INSERT INTO `t01` VALUES (1,1,10.111,'2023-03-21 01:00:00'),(2,2,19.111,'2023-03-21 01:00:00'),(3,2,11.111,'2023-03-21 02:00:00'),(4,3,12.111,'2023-03-21 02:00:00'),(5,1,13.111,'2023-03-22 11:00:00'),(6,1,14.111,'2023-03-22 12:00:00'),(7,1,15.111,'2023-03-23 12:00:00'); select distinct date(`date`) as`date`,`type`,count(*) over(partition by date(`date`),`type`) as count, first_value(`date`) over (partition by date(`date`),`type` order by `date` desc) as `latest_datetime`,first_value(`value`) over (partition by date(`date`),`type` order by `date` desc) as `latest_value` from t01; +------------+------+-------+---------------------+--------------+ | date | type | count | latest_datetime | latest_value | +------------+------+-------+---------------------+--------------+ | 2023-03-21 | 1 | 1 | 2023-03-21 01:00:00 | 10.111 | | 2023-03-21 | 2 | 2 | 2023-03-21 02:00:00 | 11.111 | | 2023-03-21 | 3 | 1 | 2023-03-21 02:00:00 | 12.111 | | 2023-03-22 | 1 | 2 | 2023-03-22 12:00:00 | 14.111 | | 2023-03-23 | 1 | 1 | 2023-03-23 12:00:00 | 15.111 | +------------+------+-------+---------------------+--------------+ |