Some checks failed
Build docker and publish / linux (1.24.5) (push) Failing after 39s
feat(抽奖动态): 修复抽奖动态未渲染问题并优化文案展示 fix(用户概览): 修复用户概览无数据显示问题 feat(新用户列表): 在新用户列表显示称号明细 refactor(待办事项): 移除代办模块并全宽展示实时动态 feat(批量操作): 限制为单用户操作并在批量时提醒 fix(称号分配): 防重复分配称号的改造计划 perf(接口性能): 优化新用户和抽奖动态接口性能 feat(订单漏斗): 优化订单转化漏斗指标计算 docs(测试计划): 完善盲盒运营API核查与闭环测试计划
3.7 KiB
3.7 KiB
痛点定位
- 新用户接口在单次请求内对每个用户做多次单表查询(资产、道具卡、优惠券、称号、最后在线时间),形成 N+1 查询,延迟随列表大小线性增加(
internal/api/admin/dashboard_admin.go的DashboardNewUsers())。 - 实时抽奖动态接口对每条抽奖日志逐条联查用户/期/活动/奖品,亦为 N+1 查询(
DashboardDrawStream())。
后端优化方案
- 批量聚合替代逐条查询(NewUsers)
- 第一步:一次查出当前页的
user_id列表 - 第二步:分别对各表做分组聚合(单次查询):
- 资产:
SELECT user_id, COUNT(*) FROM user_inventory WHERE user_id IN (...) GROUP BY user_id - 道具卡:
SELECT user_id, COUNT(*) FROM user_item_cards WHERE status=1 AND user_id IN (...) GROUP BY user_id - 优惠券:
SELECT user_id, COUNT(*) FROM user_coupons WHERE user_id IN (...) GROUP BY user_id - 称号:
SELECT ut.user_id, st.id, st.name FROM user_titles ut LEFT JOIN system_titles st ON st.id=ut.title_id WHERE ut.user_id IN (...) - 最后在线:分别取各行为表
MAX(time)按user_id聚合,再在内存求最大值 - 积分余额:改为批量查
user_points有效积分GROUP BY user_id,或接入预聚合表(见下)
- 资产:
- 第三步:用
map[user_id]value合并到用户列表,避免每行多次往返数据库
- 第一步:一次查出当前页的
- 连接查询替代逐条补全(DrawStream)
- 单条 SQL 联查:
activity_draw_logsLEFT JOINusers、activity_issues、activities、activity_reward_settings,一次性返回nickname/activityName/issueNumber/prizeName - 保留
since_id + limit增量拉取;避免循环内First()调用
- 单条 SQL 联查:
- 预聚合与缓存
- 建议增加
user_stats表(或 Redis 缓存)维护:points_balance、inventory_count、item_card_count、coupon_count、title_list、last_online_at- 更新策略:
- 同步:在相关写入路径(发放积分/道具卡/优惠券/称号、抽奖、下单)更新统计
- 异步:crontab 每 1-5 分钟增量刷新
- 更新策略:
- 实时抽奖:为最近 50 条结果加 3-5 秒内存缓存(LRU 或 Redis)
- 建议增加
- 限流与分页
- 新用户默认
page_size=20,最大 50;实时抽奖limit<=100 - 对于“今年”范围下分页检索控制页大小,避免一次返回过多用户
- 新用户默认
数据库与索引
- 新建/确认索引:
users(created_at)、users(id)activity_draw_logs(id DESC, user_id, issue_id, reward_id, created_at)user_inventory(user_id)、user_item_cards(user_id,status)、user_coupons(user_id)、user_titles(user_id,title_id)user_points(user_id, valid_end)、user_points_ledger(user_id, created_at)
- 可选:为
log_request(path, created_at)增加user_id字段与索引,精确“最后在线时间”
前端协同优化
- 新用户页签切换时:防抖 200ms;保留上次结果并显示加载骨架,避免空白闪烁
- 实时抽奖轮询:保持 5s;追加条目后裁剪到 100-200 条以保证 DOM 轻量;使用
ref持有列表(已改) - 宽度问题:动态项允许换行并分两行展示(已改),避免不可见
验收指标
- 新用户接口:在
page_size=20时 P95 响应时间 < 200ms(本地数据量下) - 实时抽奖接口:在
limit=50时 P95 响应时间 < 150ms;每轮轮询端到端显示时间 < 300ms
下一步实现内容(获批后执行)
- 重写
DashboardNewUsers()为批量聚合与合并映射 - 重写
DashboardDrawStream()为单次 LEFT JOIN 联查 - 添加必要索引迁移脚本
- 可选:落地
user_stats预聚合与写路径刷新机制
确认后我将按上述方案逐条落地并提供压测数据与对比报告。