
一个处理数据的需求,目前已经实现出来了,测试提出性能太低,所以请教一下,看看有没有比较好的处理实现方式,目前实现 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 年 3 月 28 日 via Android 问问万能的 chatgpt? |
2 dqzcwxb 2023 年 3 月 28 日 你的需求是:将数据分组 count 且需要组名 实现方案有两个: 1,用 sql 分别实现分组统计,分组组名 性能优化点就是添加有效索引和并行查询; 2,用 sql 查询出所有数据然后用 Stream groupby 做分组统计,性能优化就是开启 parallelStream 和加机器配置; |
3 godleon OP @dqzcwxb 我现在就是 sql 分组,还遇到个问题就是分组的时候 再加 desc 分组就不会倒序了,然后又加子查询 用 max 取日期值找最新的,count 就得在分,因为我上面是 demo ,真实场景下我查出来的东西近 10W 条 40+个字段,我决定纯用代码处理试试 |
4 acctv2 2023 年 3 月 28 日 via Android explain 看看? |
5 gjp0609 2023 年 3 月 28 日 sql 开窗函数应该可以实现吧 |
6 F281M6Dh8DXpD1g2 2023 年 3 月 28 日 mysql 8 直接 rank() over ( partition by )这种解决完事 |
7 Ikarosx 2023 年 3 月 28 日 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 年 3 月 28 日 期望的数据有问题吧,3-22 的 type 为 1 的数据有两条。如果确认的话窗口函数确实可以解决 |
10 Derek8863 2023 年 3 月 28 日 建议用 ck 或者 presto 做计算引擎 |
11 dode 2023 年 3 月 28 日 via Android 建议最新一条单独纯一个表 |
12 dode 2023 年 3 月 28 日 via Android 如果只有 3 种,就分别查询,再联合一下吧 |
13 crazyweeds 2023 年 3 月 28 日 如果你返回条目数小的情况下,可以尝试代码层面多线程。SQL 拿到最新的日期列表,然后用日期作为参数,多线程循环执行 SQL 。 |
14 fizzzzz 2023 年 3 月 28 日 如果项目中引入了 guava 可以看下 Multimap 类型 |
15 noparking188 2023 年 3 月 28 日 最好补充以下信息,决定方案选择 1. 数据更新频率; 2. 预估数据总量; 3. 数据查询频率; 4. 查询响应要求; Java 后端里写业务逻辑对 MySQL 中的数据做复杂**分析**处理?也许提供业务场景上下文更清晰一点 |
16 14104chk 2023 年 3 月 28 日 可以用一张统计表,修改的时候,把当前日期的统计数据更新 |
17 luzemin 2023 年 3 月 28 日 同意楼上 要想让读路径短一些,那就让写路径长一些。 在写入的时候,把需要的结果单独更新到某个表 /位置。 |
18 wenxueywx 2023 年 3 月 29 日 @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 | +------------+------+-------+---------------------+--------------+ |