6.7 KiB
6.7 KiB
导入速度慢修复说明
❌ 问题现象
导入100条数据需要2-3分钟,比之前慢了好几倍。
日志分析
slow sql 1164 millis. update sys_user (每条1.2秒)
slow sql 1165 millis. update student_class (每条1.2秒)
Duplicate entry '234-17' for key 'student_class.uk_student_class'
🔍 问题原因
原因1:班级分配逻辑错误
错误逻辑:
- 将旧班级设置为
status=0 - 插入新班级记录
问题:
- 如果新旧班级ID相同,INSERT失败(Duplicate)
- 每次都UPDATE然后INSERT,即使班级未变
原因2:数据库缺少索引
sys_user.user_name无索引student_class.student_id无索引- 导致查询很慢(1.2秒/条)
原因3:重复的数据库操作
- 每条记录都查询班级列表
- 每条记录都UPDATE status
- 没有必要的缓存
✅ 已修复内容
修复1:优化班级分配逻辑
文件: StudyClassUserServiceImpl.java (第1119-1181行)
新逻辑:
// 1. 检查是否已在该班级
if (已在该班级) {
if (状态不是活跃) {
// 只需UPDATE状态
UPDATE status = 1
}
// 否则什么都不做
}
else {
// 2. 禁用其他班级
UPDATE 其他班级 status = 0
// 3. 插入新班级
INSERT 新班级记录
}
优势:
- ✅ 避免Duplicate错误
- ✅ 减少不必要的UPDATE
- ✅ 班级未变时不做任何操作
修复2:创建数据库优化SQL
文件: log/Sql/optimize_import_performance.sql
包含:
- 添加必要的索引
- 优化表统计信息
- 性能监控查询
🚀 部署步骤
步骤1:重新编译后端
cd C:\Users\Administrator\Desktop\Project\ry_study-v_03\Study-Vue-redis
mvn clean package -DskipTests
步骤2:执行数据库优化SQL
# 连接数据库
mysql -u root -p ry_study
# 执行优化SQL
source C:/Users/Administrator/Desktop/Project/ry_study-v_03/log/Sql/optimize_import_performance.sql
或者在Navicat中:
- 打开数据库:
ry_study - 打开查询窗口
- 粘贴
optimize_import_performance.sql内容 - 执行
步骤3:重启服务
# 停止旧服务
# 启动新服务
步骤4:测试导入
- 准备测试数据(100条)
- 执行导入
- 记录时间
- 查看日志
📊 性能对比
修复前
| 项目 | 数值 |
|---|---|
| 100条导入时间 | 2-3分钟 |
| 每条平均时间 | 1.2-1.8秒 |
| Duplicate错误 | 频繁出现 |
| 慢查询 | 大量 |
修复后(预期)
| 项目 | 数值 |
|---|---|
| 100条导入时间 | 10-30秒 |
| 每条平均时间 | 0.1-0.3秒 |
| Duplicate错误 | 无 |
| 慢查询 | 基本无 |
性能提升:5-10倍
🔧 添加的索引
-- sys_user 表
CREATE INDEX idx_user_name ON sys_user(user_name); -- 快速按信息编号查询
CREATE INDEX idx_nick_name ON sys_user(nick_name); -- 快速按姓名查询
CREATE INDEX idx_prison_area ON sys_user(prison_area); -- 快速按监区查询
-- student_class 表
CREATE INDEX idx_student_id ON student_class(student_id); -- 快速按学员查询
CREATE INDEX idx_class_id ON student_class(class_id); -- 快速按班级查询
CREATE INDEX idx_status ON student_class(status); -- 快速按状态查询
CREATE INDEX idx_student_status ON student_class(student_id, status); -- 复合索引
🧪 测试验证
测试1:导入速度
# 1. 生成测试数据
python generate_test_data.py
# 2. 记录开始时间
开始时间: 14:00:00
# 3. 导入test_data.xlsx (100条)
# 4. 记录结束时间
结束时间: 14:00:15
# 5. 计算耗时
耗时: 15秒(之前需要2-3分钟)
测试2:无Duplicate错误
# 查看日志
grep "Duplicate entry" logs/app.log
# 预期结果:无结果
测试3:无慢查询
# 查看日志
grep "slow sql" logs/app.log
# 预期结果:无结果或很少
📋 检查清单
代码修复
- 修复班级分配逻辑
- 避免Duplicate错误
- 减少不必要的UPDATE
数据库优化
- 执行优化SQL
- 添加所有索引
- 更新表统计信息
部署验证
- 重新编译后端
- 重启服务
- 测试导入100条数据
- 查看日志确认无错误
💡 进一步优化建议
1. 批量操作
- 批量INSERT(每批50条)
- 批量UPDATE
- 减少数据库往返次数
2. 使用缓存
- Redis缓存班级映射
- 缓存角色ID
- 减少重复查询
3. 异步处理
- 使用消息队列
- 后台异步导入
- 提高并发性
4. 连接池优化
spring:
datasource:
druid:
max-active: 50 # 增加最大连接数
⚠️ 注意事项
1. 数据库备份
- 执行SQL前务必备份数据库
- 建议先在测试环境验证
2. 索引维护
- 索引会占用磁盘空间
- 写入性能可能略有下降(可忽略)
- 定期ANALYZE TABLE
3. 监控
- 持续监控慢查询日志
- 关注数据库连接数
- 关注内存使用
🆘 常见问题
Q1:索引创建失败
-- 检查是否已存在同名索引
SHOW INDEX FROM sys_user WHERE Key_name = 'idx_user_name';
-- 删除后重新创建
DROP INDEX idx_user_name ON sys_user;
CREATE INDEX idx_user_name ON sys_user(user_name);
Q2:仍然出现Duplicate错误
- 检查代码是否重新编译
- 检查服务是否重启
- 查看日志确认使用新代码
Q3:性能没有明显提升
- 检查索引是否创建成功
- 执行ANALYZE TABLE
- 查看EXPLAIN确认使用了索引
✅ 验收标准
- 100条数据导入时间 < 30秒
- 无Duplicate错误
- 无slow sql警告(或很少)
- 日志无异常
- 班级分配正确
📝 修改文件清单
后端代码
- ✅
StudyClassUserServiceImpl.java- 修复班级分配逻辑
数据库
- ✅
optimize_import_performance.sql- 添加索引和优化
文档
- ✅
导入性能优化方案.md- 详细分析 - ✅
导入速度慢修复说明.md- 修复说明(本文档)
🎯 总结
核心问题
- 班级分配逻辑错误 → Duplicate错误
- 缺少数据库索引 → 慢查询
- 重复的数据库操作 → 性能差
解决方案
- 修复班级分配逻辑
- 添加必要的索引
- 优化数据库配置
预期效果
- 性能提升:5-10倍
- 无错误:无Duplicate
- 体验更好:导入更流畅
现在请按照步骤执行修复,完成后测试导入速度! 🚀