修复 Promotion-List 接口的严重性能问题,该接口在查询推广团队成员列表时出现超时,执行时间超过2分钟。
Promotion-List,参数:{"page":{"page":"2","perPage":"10"},"level":"1"}cURL error 28: Operation timed out after 30002 millisecondsselect urs_user_id from kku_urs_promotion_user_referrals where urs_referrer_id = ? and status = 1性能瓶颈在 getTeamMemberData 方法:
UrsReferralService::getTeamMembers($ursUserId) 无参数,默认查询20代getTeamMembers() 方法使用递归查询,对每个用户都调用 getDirectReferrals()// 问题代码
$teamMembers = UrsReferralService::getTeamMembers($ursUserId); // 查询20代
if ($level == 1) {
// 只使用1代数据,其他19代查询都是浪费
$filteredMembers = $teamMembers[1];
}
将递归查询改为使用 UrsUserRelationCache 缓存表:
优化前:
// 递归查询20代,产生数百次SQL查询
$teamMembers = UrsReferralService::getTeamMembers($ursUserId);
优化后:
// 直接查询缓存表,只查询指定层级
$query = UrsUserRelationCache::where('related_user_id', $farmUserId);
if ($level == 1) {
$query->where('depth', 1); // 只查询1代
}
优化前:查询所有数据后在内存中分页 优化后:在数据库层面进行分页查询
根据 level 参数精确查询指定层级,避免不必要的数据查询。
文件:app/Module/AppGame/Handler/Promotion/ListHandler.php
主要修改:
getTeamMemberData() 方法UrsUserRelationCache 缓存表替代递归查询level 参数精确查询指定层级关键查询优化:
-- 统计总数
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 ?
urs_promotion_user_referrals 表urs_promotion_user_relation_cache 表(count + select)使用 php artisan debug:reproduce-error 69223552 重放原始请求:
UrsUserRelationCache 表的设计很好地支持了这种查询优化:
related_user_id:上级用户ID,用于查询某用户的所有下级depth:层级深度,支持精确查询指定层级Commit: eb917d51
优化Promotion-List接口性能:使用缓存表替代递归查询
- 修改getTeamMemberData方法,使用UrsUserRelationCache缓存表查询
- 避免递归调用getTeamMembers方法查询20代数据的性能问题
- 根据level参数精确查询指定层级,避免不必要的数据查询
- 在数据库层面进行分页,提升查询效率
- 性能提升约38倍:从141秒优化到3.7秒
- 移除不再使用的UrsReferralService和AccountService导入
UrsReferralService::getTeamMembers() 的地方UrsUserRelationCache 表的数据及时更新