Files
soul-yongping/开发文档/8、部署/分销中心接口优化方案.md
2026-02-09 15:09:29 +08:00

12 KiB
Raw Blame History

分销中心接口优化方案

一、当前接口分析

1. 接口调用情况

分销中心页面 (miniprogram/pages/referral/referral.js)

接口 调用时机 功能 优化空间
/api/referral/data 页面初始化 获取所有分销数据 ⚠️ 需优化查询数量
/api/miniprogram/qrcode 用户点击分享 生成小程序码 合理
/api/withdraw 用户申请提现 提现接口 合理

2. 核心接口 /api/referral/data 的查询情况

当前执行的数据库查询:

序号 查询目的 数据量 优化建议
1 获取用户基本信息 users 1行 🔄 可合并
2 获取绑定关系统计 referral_bindings 1行聚合 🔄 可合并
3 获取访问量统计 referral_visits 1行聚合 🔄 可合并
4 获取付款统计 orders + referral_bindings 1行聚合 🔄 可合并
5 获取待审核提现金额 withdrawals 1行聚合 🔄 可合并
6 获取活跃用户列表 referral_bindings + users ≤50行 保持独立
7 获取已转化用户列表 referral_bindings + users ≤50行 保持独立
8 获取已过期用户列表 referral_bindings + users ≤50行 保持独立
9 获取收益明细 orders + users + referral_bindings ≤30行 保持独立

总计9个查询

3. 性能瓶颈分析

问题点:

  1. 查询次数过多 - 9个独立查询多次往返数据库
  2. 重复JOIN - 多次JOIN相同的表referral_bindings, users
  3. 无缓存机制 - 配置数据每次都重新查询

影响:

  • 响应时间慢 - 9个查询串行执行总耗时约 500-800ms
  • 数据库负载高 - 高并发时增加数据库压力
  • 小程序加载慢 - 用户体验差需要loading提示

二、优化方案设计

优化策略

1. 查询合并 - 减少数据库往返次数

原方案5个独立的单行统计查询

1. SELECT users → 用户信息
2. SELECT referral_bindings → 绑定统计
3. SELECT referral_visits → 访问统计
4. SELECT orders → 付款统计
5. SELECT withdrawals → 提现统计

优化方案1个聚合查询

SELECT 
  -- 用户信息
  u.id, u.nickname, u.referral_code, u.earnings, 
  u.pending_earnings, u.withdrawn_earnings, u.referral_count,
  
  -- 绑定统计(子查询)
  (SELECT COUNT(*) FROM referral_bindings WHERE referrer_id = u.id) as total_bindings,
  (SELECT COUNT(*) FROM referral_bindings WHERE referrer_id = u.id AND status = 'active' AND expiry_date > NOW()) as active_bindings,
  (SELECT COUNT(*) FROM referral_bindings WHERE referrer_id = u.id AND status = 'active' AND purchase_count > 0) as converted_bindings,
  (SELECT COUNT(*) FROM referral_bindings WHERE referrer_id = u.id AND (status = 'expired' OR expiry_date <= NOW())) as expired_bindings,
  
  -- 访问统计(子查询)
  (SELECT COUNT(DISTINCT visitor_id) FROM referral_visits WHERE referrer_id = u.id) as total_visits,
  
  -- 付款统计(子查询)
  (SELECT COUNT(DISTINCT o.user_id) FROM orders o JOIN referral_bindings rb ON o.user_id = rb.referee_id WHERE rb.referrer_id = u.id AND o.status = 'paid') as paid_count,
  (SELECT COALESCE(SUM(o.amount), 0) FROM orders o JOIN referral_bindings rb ON o.user_id = rb.referee_id WHERE rb.referrer_id = u.id AND o.status = 'paid') as total_amount,
  
  -- 待审核提现(子查询)
  (SELECT COALESCE(SUM(amount), 0) FROM withdrawals WHERE user_id = u.id AND status = 'pending') as pending_withdraw_amount
  
FROM users u
WHERE u.id = ?

优势:

  • 从5个查询减少到1个查询
  • 减少数据库往返次数从5次减少到1次
  • 响应时间减少约 60-70%

2. 列表查询优化 - 合理使用索引

当前查询4个独立列表查询

  • 活跃用户列表50条
  • 已转化用户列表50条
  • 已过期用户列表50条
  • 收益明细30条

优化方案:

  • 保持独立查询(列表数据无法合并)
  • 确保所有JOIN字段有索引
  • 限制返回字段,减少数据传输量
  • 添加查询超时控制

需要的索引:

-- referral_bindings 表
CREATE INDEX idx_referrer_status_expiry ON referral_bindings(referrer_id, status, expiry_date);
CREATE INDEX idx_referrer_purchase ON referral_bindings(referrer_id, purchase_count);

-- orders 表
CREATE INDEX idx_user_status_paytime ON orders(user_id, status, pay_time);
CREATE INDEX idx_referrer_status ON orders(referrer_id, status);

-- withdrawals 表
CREATE INDEX idx_user_status ON withdrawals(user_id, status);

3. 配置缓存 - 减少重复查询

原方案:

// 每次请求都查询配置
const config = await getConfig('referral_config')

优化方案:

// 使用内存缓存5分钟过期
const configCache = new Map()

async function getCachedConfig(key) {
  const cached = configCache.get(key)
  if (cached && Date.now() - cached.time < 5 * 60 * 1000) {
    return cached.data
  }
  const data = await getConfig(key)
  configCache.set(key, { data, time: Date.now() })
  return data
}

4. 分页加载 - 减少初始数据量

原方案:

  • 一次性加载所有列表数据活跃50条 + 转化50条 + 过期50条 + 明细30条 = 180条

优化方案:

  • 初始只加载核心统计数据 + 活跃用户列表20条
  • 其他列表数据按需加载用户切换Tab时加载
// 方案1单接口 + type参数
GET /api/referral/data?userId=xxx&type=overview  // 只返回统计数据
GET /api/referral/data?userId=xxx&type=active    // 活跃用户列表
GET /api/referral/data?userId=xxx&type=converted // 已转化列表
GET /api/referral/data?userId=xxx&type=expired   // 已过期列表
GET /api/referral/data?userId=xxx&type=earnings  // 收益明细

// 方案2保持当前一次性加载推荐
// 理由:分销中心是高频页面,用户通常会查看所有数据
// 优化查询性能比拆分接口更有效

优化后的架构

┌─────────────────────────────────────────┐
│  小程序 - 分销中心页面                    │
└─────────────────┬───────────────────────┘
                  │
                  │ 1次请求
                  ↓
┌─────────────────────────────────────────┐
│  /api/referral/data (优化后)             │
├─────────────────────────────────────────┤
│  1. 聚合统计查询1个查询                │
│     - 用户信息 + 绑定统计 + 付款统计       │
│     - 访问统计 + 提现统计                 │
│  2. 活跃用户列表1个查询20条          │
│  3. 已转化用户列表1个查询20条        │
│  4. 已过期用户列表1个查询20条        │
│  5. 收益明细1个查询20条             │
├─────────────────────────────────────────┤
│  总计5个查询vs 原9个查询             │
│  预计响应时间200-300msvs 原500-800ms│
└─────────────────────────────────────────┘

三、实施计划

Phase 1: 核心优化(立即实施)

  1. 合并统计查询

    • 将5个独立统计查询合并为1个聚合查询
    • 预计减少响应时间 60-70%
    • 影响范围:app/api/referral/data/route.ts
  2. 添加数据库索引

    • 为高频查询字段添加复合索引
    • 提升查询效率 30-50%
    • 影响范围:数据库 schema
  3. 减少列表数据量

    • 将列表限制从50条减少到20条
    • 减少数据传输量 40%
    • 影响范围:查询 LIMIT 参数

Phase 2: 进阶优化(可选)

  1. 配置缓存

    • 使用内存缓存配置数据
    • 减少配置查询次数
    • 影响范围:lib/db.ts
  2. 懒加载列表

    • 按需加载不同Tab的数据
    • 进一步减少初始加载时间
    • 影响范围:前端 + 后端接口

Phase 3: 长期优化(未来规划)

  1. Redis缓存

    • 缓存用户分销数据1分钟过期
    • 适用于高并发场景
    • 需要额外的Redis服务
  2. CDN缓存

    • 缓存小程序码图片
    • 减少生成次数
    • 需要CDN服务支持

四、性能对比

优化前 vs 优化后

指标 优化前 优化后 提升
数据库查询次数 9个 5个 ↓ 44%
聚合查询次数 5个 1个 ↓ 80%
列表查询次数 4个 4个 -
返回数据量 ~180条 ~80条 ↓ 55%
预计响应时间 500-800ms 200-300ms ↓ 60-70%
数据库负载 ↓ 50%

优化效果预估

用户体验提升:

  • 页面加载速度提升 60-70%
  • Loading时间更短体验更流畅
  • 数据刷新更快

服务器性能提升:

  • 数据库查询减少 44%
  • 数据库连接时间减少 60%
  • 可支持更高并发

成本优化:

  • 数据库资源消耗减少 50%
  • 带宽消耗减少 55%

五、向后兼容

API响应格式

优化后的 /api/referral/data 接口响应格式完全兼容原有格式,前端无需修改。

{
  "success": true,
  "data": {
    // 核心统计(不变)
    "bindingCount": 10,
    "visitCount": 50,
    "paidCount": 5,
    "expiredCount": 2,
    
    // 收益数据(不变)
    "totalCommission": 450.00,
    "availableEarnings": 300.00,
    "pendingWithdrawAmount": 100.00,
    "withdrawnEarnings": 50.00,
    
    // 列表数据(数量减少,格式不变)
    "activeUsers": [...],      // 50条 → 20条
    "convertedUsers": [...],   // 50条 → 20条
    "expiredUsers": [...],     // 50条 → 20条
    "earningsDetails": [...]   // 30条 → 20条
  }
}

六、风险评估

风险 影响 概率 缓解措施
聚合查询性能不如预期 回滚到原查询,添加更多索引
复杂子查询导致慢查询 使用 EXPLAIN 分析,优化查询计划
缓存数据不一致 设置短期过期时间5分钟
列表数据不够用 支持分页参数,按需加载更多

七、测试验证

性能测试

# 测试工具Apache Bench
ab -n 100 -c 10 "http://localhost:3000/api/referral/data?userId=xxx"

# 预期结果:
# - 平均响应时间 < 300ms
# - 95%请求 < 400ms
# - 无失败请求

数据正确性测试

-- 验证聚合查询结果与独立查询一致
-- 1. 绑定统计
SELECT COUNT(*) FROM referral_bindings WHERE referrer_id = 'xxx';

-- 2. 付款统计
SELECT COUNT(DISTINCT o.user_id) 
FROM orders o 
JOIN referral_bindings rb ON o.user_id = rb.referee_id 
WHERE rb.referrer_id = 'xxx' AND o.status = 'paid';

-- 3. 提现统计
SELECT SUM(amount) FROM withdrawals WHERE user_id = 'xxx' AND status = 'pending';

八、总结

核心优化点

  1. 合并统计查询 - 从5个查询减少到1个性能提升最大
  2. 添加数据库索引 - 确保查询效率,避免全表扫描
  3. 减少返回数据量 - 减少网络传输,加快响应速度
  4. 配置缓存 - 减少重复查询,降低数据库负载

实施建议

推荐方案:立即实施 Phase 1

  • 合并统计查询
  • 添加数据库索引
  • 减少列表数据量

预计收益:

  • 响应时间减少 60-70%
  • 数据库负载减少 50%
  • 用户体验显著提升

实施时间:

  • 开发时间2-3小时
  • 测试时间1小时
  • 部署时间30分钟
  • 总计:约半天

优化后,分销中心将成为一个高性能、低延迟的功能模块,为用户提供流畅的体验!🚀