Java7环境下文档大小计算功能的性能优化方案咨询
核心优化方向
查询层面优化
- 新增覆盖索引:给
DOCS表创建(RECK, CURRENT)联合索引,同时将SIZE、NAME字段加入索引作为覆盖字段,避免查询回表,SQL执行速度可提升数倍。建索引参考语句:
-- 支持INCLUDE语法的数据库(如PostgreSQL、SQL Server)用以下语句 CREATE INDEX idx_docs_reck_current ON DOCS(RECK, CURRENT) INCLUDE (SIZE, NAME); -- 不支持INCLUDE的数据库直接建联合索引 CREATE INDEX idx_docs_reck_current ON DOCS(RECK, CURRENT, SIZE, NAME);
- 移除冗余COUNT查询:原代码对同一份筛选条件执行了两次数据库请求,一次查文档列表、一次查记录数,完全可以通过一次查询遍历ResultSet同时完成计数和大小累加,省掉一次数据库IO开销,高并发场景下性能提升明显。
- 统一使用预编译SQL:原COUNT查询直接拼接
id参数,存在SQL注入风险,同时数据库无法复用执行计划,所有涉及参数的SQL都改用预编译写法。 - 按需查询字段:如果
NAME字段没有实际使用逻辑,直接从查询SQL中移除,减少数据传输开销。
计算&代码逻辑层面优化
- 单次遍历完成所有计算:不需要先查COUNT再遍历结果集,直接一次遍历ResultSet同时统计总大小、记录数,遍历完成后再根据记录数判断返回逻辑,减少结果集遍历次数。
- 优化SIZE字段处理逻辑:
- 允许改表的前提下,将SIZE拆分为数值类型的
size_value和单位字段size_unit,从根源上避免每次查询都要做字符串截取、类型转换的开销; - 不能改表的话可以在SQL层面直接完成SIZE到数值的转换,例如MySQL可以用
CAST(TRIM(TRAILING 'o' FROM SIZE) AS UNSIGNED) AS size_num,数据库层面完成转换比Java端反复处理字符串性能更高。
- 允许改表的前提下,将SIZE拆分为数值类型的
- 补充资源释放逻辑:原代码没有手动关闭ResultSet,容易出现数据库连接泄漏,用Java7支持的try-with-resources自动释放资源,避免连接池耗尽导致的性能下降。
优化后代码示例
int totalSize = 0; int count = 0; String singleSize = null; String name = null; List<DBUtil.Field> fields = new ArrayList<>(); fields.add(new DBUtil.Field("RECK", id)); // 可根据需要调整SQL,不需要NAME就删掉该字段 String sql = "SELECT SIZE, NAME from DOCS WHERE RECK=? AND CURRENT='true'"; // try-with-resources自动关闭ResultSet,避免资源泄漏 try (ResultSet rs1 = db.execQueryPrepareStatement("DOCS", sql, fields)) { while (rs1.next()) { count++; String sizeStr = rs1.getString("SIZE"); // 只存第一条的size,单条记录时直接返回 if (count == 1) { singleSize = sizeStr; name = rs1.getString("NAME"); } // 统一累加数值,避免重复处理字符串 totalSize += Integer.parseInt(sizeStr.substring(0, sizeStr.length() - 1)); } if (count == 1) { element.setSIZE(singleSize); } else if (count > 1) { element.setSIZE(totalSize + "o"); } }
内容的提问来源于stack exchange,提问作者JDOE
相关产品推荐
相关产品推荐

