|
|
@@ -0,0 +1,176 @@
|
|
|
+# Promotion-List接口性能优化
|
|
|
+
|
|
|
+## 任务概述
|
|
|
+修复 Promotion-List 接口的严重性能问题,该接口在查询推广团队成员列表时出现超时,执行时间超过2分钟。
|
|
|
+
|
|
|
+## 任务时间
|
|
|
+- **开始时间**:2025年07月05日 00:09:24 CST
|
|
|
+- **完成时间**:2025年07月05日 00:15:00 CST
|
|
|
+- **总耗时**:约6分钟
|
|
|
+
|
|
|
+## 问题分析
|
|
|
+
|
|
|
+### 1. 问题现象
|
|
|
+- 请求:`Promotion-List`,参数:`{"page":{"page":"2","perPage":"10"},"level":"1"}`
|
|
|
+- 执行时间:141168ms(约2.5分钟)
|
|
|
+- 最终超时失败:`cURL error 28: Operation timed out after 30002 milliseconds`
|
|
|
+- 日志显示大量SQL查询:`select urs_user_id from kku_urs_promotion_user_referrals where urs_referrer_id = ? and status = 1`
|
|
|
+
|
|
|
+### 2. 根本原因
|
|
|
+**性能瓶颈在 `getTeamMemberData` 方法**:
|
|
|
+1. 第146行调用 `UrsReferralService::getTeamMembers($ursUserId)` 无参数,默认查询20代
|
|
|
+2. 即使用户只要1代数据(level=1),系统还是查询了20代所有数据
|
|
|
+3. `getTeamMembers()` 方法使用递归查询,对每个用户都调用 `getDirectReferrals()`
|
|
|
+4. 产生数百次数据库查询,造成性能爆炸
|
|
|
+
|
|
|
+### 3. 逻辑问题
|
|
|
+```php
|
|
|
+// 问题代码
|
|
|
+$teamMembers = UrsReferralService::getTeamMembers($ursUserId); // 查询20代
|
|
|
+if ($level == 1) {
|
|
|
+ // 只使用1代数据,其他19代查询都是浪费
|
|
|
+ $filteredMembers = $teamMembers[1];
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+## 解决方案
|
|
|
+
|
|
|
+### 1. 使用缓存表优化查询
|
|
|
+将递归查询改为使用 `UrsUserRelationCache` 缓存表:
|
|
|
+
|
|
|
+**优化前**:
|
|
|
+```php
|
|
|
+// 递归查询20代,产生数百次SQL查询
|
|
|
+$teamMembers = UrsReferralService::getTeamMembers($ursUserId);
|
|
|
+```
|
|
|
+
|
|
|
+**优化后**:
|
|
|
+```php
|
|
|
+// 直接查询缓存表,只查询指定层级
|
|
|
+$query = UrsUserRelationCache::where('related_user_id', $farmUserId);
|
|
|
+if ($level == 1) {
|
|
|
+ $query->where('depth', 1); // 只查询1代
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+### 2. 数据库层面分页
|
|
|
+**优化前**:查询所有数据后在内存中分页
|
|
|
+**优化后**:在数据库层面进行分页查询
|
|
|
+
|
|
|
+### 3. 精确查询层级
|
|
|
+根据 `level` 参数精确查询指定层级,避免不必要的数据查询。
|
|
|
+
|
|
|
+## 修改内容
|
|
|
+
|
|
|
+### 1. 核心方法重构
|
|
|
+文件:`app/Module/AppGame/Handler/Promotion/ListHandler.php`
|
|
|
+
|
|
|
+**主要修改**:
|
|
|
+- 重构 `getTeamMemberData()` 方法
|
|
|
+- 使用 `UrsUserRelationCache` 缓存表替代递归查询
|
|
|
+- 根据 `level` 参数精确查询指定层级
|
|
|
+- 在数据库层面进行分页
|
|
|
+- 移除不再使用的导入
|
|
|
+
|
|
|
+**关键查询优化**:
|
|
|
+```sql
|
|
|
+-- 统计总数
|
|
|
+SELECT COUNT(*) FROM kku_urs_promotion_user_relation_cache
|
|
|
+WHERE related_user_id = ? AND depth = ?
|
|
|
+
|
|
|
+-- 分页查询
|
|
|
+SELECT * FROM kku_urs_promotion_user_relation_cache
|
|
|
+WHERE related_user_id = ? AND depth = ?
|
|
|
+ORDER BY depth ASC, user_id ASC
|
|
|
+LIMIT ? OFFSET ?
|
|
|
+```
|
|
|
+
|
|
|
+## 性能提升
|
|
|
+
|
|
|
+### 1. 执行时间对比
|
|
|
+- **优化前**:141168ms(约2.5分钟)
|
|
|
+- **优化后**:3717ms(约3.7秒)
|
|
|
+- **性能提升**:约 **38倍**
|
|
|
+
|
|
|
+### 2. SQL查询对比
|
|
|
+- **优化前**:数百次递归查询 `urs_promotion_user_referrals` 表
|
|
|
+- **优化后**:2次查询 `urs_promotion_user_relation_cache` 表(count + select)
|
|
|
+
|
|
|
+### 3. 资源消耗
|
|
|
+- **优化前**:大量数据库连接和查询,内存占用高
|
|
|
+- **优化后**:最小化数据库查询,内存占用低
|
|
|
+
|
|
|
+## 测试验证
|
|
|
+
|
|
|
+### 1. 功能测试
|
|
|
+使用 `php artisan debug:reproduce-error 69223552` 重放原始请求:
|
|
|
+- ✅ 请求成功返回
|
|
|
+- ✅ 数据正确:total=54,返回第2页10条数据
|
|
|
+- ✅ 分页信息正确:currentPage=2, perPage=10, hasMore=true, lastPage=6
|
|
|
+
|
|
|
+### 2. 性能测试
|
|
|
+- ✅ 执行时间从141秒降低到3.7秒
|
|
|
+- ✅ SQL查询从数百次降低到2次
|
|
|
+- ✅ 无超时错误
|
|
|
+
|
|
|
+## 技术要点
|
|
|
+
|
|
|
+### 1. 缓存表设计
|
|
|
+`UrsUserRelationCache` 表的设计很好地支持了这种查询优化:
|
|
|
+- `related_user_id`:上级用户ID,用于查询某用户的所有下级
|
|
|
+- `depth`:层级深度,支持精确查询指定层级
|
|
|
+- 索引优化:支持高效的分页查询
|
|
|
+
|
|
|
+### 2. 查询策略
|
|
|
+- 避免N+1查询问题
|
|
|
+- 使用数据库层面的分页和排序
|
|
|
+- 根据业务需求精确查询,避免过度查询
|
|
|
+
|
|
|
+### 3. 向后兼容
|
|
|
+- 保持API接口不变
|
|
|
+- 返回数据格式完全一致
|
|
|
+- 不影响其他功能模块
|
|
|
+
|
|
|
+## 业务影响
|
|
|
+
|
|
|
+### 1. 用户体验提升
|
|
|
+- 推广列表加载速度大幅提升
|
|
|
+- 避免接口超时导致的用户体验问题
|
|
|
+- 提高系统响应性能
|
|
|
+
|
|
|
+### 2. 系统稳定性
|
|
|
+- 减少数据库压力
|
|
|
+- 降低系统资源消耗
|
|
|
+- 提高并发处理能力
|
|
|
+
|
|
|
+### 3. 可扩展性
|
|
|
+- 为后续功能扩展奠定基础
|
|
|
+- 缓存表设计支持更复杂的查询需求
|
|
|
+
|
|
|
+## 提交记录
|
|
|
+
|
|
|
+**Commit**: eb917d51
|
|
|
+```
|
|
|
+优化Promotion-List接口性能:使用缓存表替代递归查询
|
|
|
+
|
|
|
+- 修改getTeamMemberData方法,使用UrsUserRelationCache缓存表查询
|
|
|
+- 避免递归调用getTeamMembers方法查询20代数据的性能问题
|
|
|
+- 根据level参数精确查询指定层级,避免不必要的数据查询
|
|
|
+- 在数据库层面进行分页,提升查询效率
|
|
|
+- 性能提升约38倍:从141秒优化到3.7秒
|
|
|
+- 移除不再使用的UrsReferralService和AccountService导入
|
|
|
+```
|
|
|
+
|
|
|
+## 后续建议
|
|
|
+
|
|
|
+### 1. 监控优化效果
|
|
|
+- 持续监控 Promotion-List 接口的性能表现
|
|
|
+- 关注缓存表的数据一致性
|
|
|
+
|
|
|
+### 2. 类似问题排查
|
|
|
+- 检查其他使用 `UrsReferralService::getTeamMembers()` 的地方
|
|
|
+- 评估是否需要类似的优化
|
|
|
+
|
|
|
+### 3. 缓存表维护
|
|
|
+- 确保 `UrsUserRelationCache` 表的数据及时更新
|
|
|
+- 监控缓存表的数据完整性
|