后端——taos数据库优化
拿到需求的第一时间就想到在业务层进行聚合操作,但是后面发现实在是太慢了,统计数据得5分钟,后面优化了之后可以不到5秒钟完成统计。(数据量:400w)对于同一个需求,这样真的快了不少,代码也少了不少,天,之前怎么没想到!在业务层使用stream流实现聚合操作,没有充分利用taos数据库的聚合函数,在数据库层对40w数据做聚合操作只需要不到1s。根据分组条件,使用taos聚合操作在持久层进行聚合操作。
·
这是对之前做的一篇文章的优化——后端——Java Stream流多字段分组 业务层实现sql的分组聚合功能。拿到需求的第一时间就想到在业务层进行聚合操作,但是后面发现实在是太慢了,统计数据得5分钟,后面优化了之后可以不到5秒钟完成统计。(数据量:400w)
优化分析
在业务层使用stream流实现聚合操作,没有充分利用taos数据库的聚合函数,在数据库层对40w数据做聚合操作只需要不到1s。
优化步骤:
根据分组条件,使用taos聚合操作在持久层进行聚合操作
在根据分组条件去找其他字段(一条记录即可)
直接上代码
service
@Service
@Slf4j
public class TaosServiceImpl implements TaosService {
@Autowired
private TaosMapper taosMapper;
/**
* 根据时间区间统计实时数据
* @param startTime
* @param endTime
* @return
*/
/*
业务层实现以下sql
SELECT COUNT(id) weldDuration,weldModel,gatherNo,welderNo,weldStatus,machineId,machineNo,
machineDeptId,gatherId,gatherDeptId,welderId,welderName,welderDeptId,taskId,taskName,taskNo,SYSDATE(),
'${startTime}','${endTime}',AVG(electricity),AVG(voltage),AVG(wireFeedRate),AVG(wireDiameter),AVG(wireMaterialsGases),
AVG(gasesFlow),walkSpeed
FROM `base_cloud_weldmes_rtdata`.${tableName}
WHERE weldTime BETWEEN #{startTime} AND #{endTime}
GROUP BY gatherNo, weldStatus, welderNo
*/
@Override
public List<OtcV2RtDataDb> getWeldStatisticsData(String startTime, String endTime) {
List<OtcV2RtDataDb> totalStatisticsData = new ArrayList<>();
// 查询数据中的表明
List<String> tables = taosMapper.showTables();
// 根据表名和时间区间查询实时数据
for (String table : tables) {
// 先查询统计数据的聚合数据
List<OtcV2RtDataDb> statisticsData = taosMapper.getStatisticsData(startTime, endTime, table);
// 再查询统计数据的其他字段
statisticsData.forEach(temp -> {
OtcV2RtDataDb otherColumn = taosMapper.getStatisticsDataOtherColumn(table, temp.getGatherNo(), temp.getWeldStatus(), temp.getWelderNo());
setOtherColumn(otherColumn, temp);
});
totalStatisticsData.addAll(statisticsData);
}
return totalStatisticsData;
}
private void setOtherColumn(OtcV2RtDataDb source, OtcV2RtDataDb target) {
target.setWeldModel(source.getWeldModel());
target.setMachineId(source.getMachineId());
target.setMachineNo(source.getMachineNo());
target.setMachineDeptId(source.getMachineDeptId());
target.setGatherId(source.getGatherId());
target.setGatherDeptId(source.getGatherDeptId());
target.setWelderId(source.getWelderId());
target.setWelderName(source.getWelderName());
target.setWelderDeptId(source.getWelderDeptId());
target.setTaskId(source.getTaskId());
target.setTaskName(source.getTaskName());
target.setTaskNo(source.getTaskNo());
}
}
mapper.xml
<select id="getStatisticsData" resultMap="TdInsertDTOResult">
SELECT gatherNo, weldStatus, welderNo,
'#{startTime}' startTime,
'#{endTime}' endTime,
COUNT(ts) weldDuration,
AVG(electricity) electricity,
AVG(voltage) voltage,
AVG(wireFeedRate) wireFeedRate,
AVG(wireDiameter) wireDiameter,
AVG(wireMaterialsGases) wireMaterialsGases,
AVG(gasesFlow) gasesFlow
FROM #{tableName} WHERE weldTime BETWEEN #{startTime} AND #{endTime}
GROUP BY gatherNo, weldStatus, welderNo
</select>
<select id="getStatisticsDataOtherColumn" resultMap="TdInsertDTOResult">
SELECT *
FROM #{tableName}
WHERE gatherNo = #{gatherNo} and weldStatus = #{weldStatus} and welderNo = #{welderNo} limit 1;
</select>
对于同一个需求,这样真的快了不少,代码也少了不少,天,之前怎么没想到!前面一篇文章就当对stream流groupingBy的学习了
更多推荐
所有评论(0)