You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优化多时间维度API循环逻辑?解决重复循环性能问题

性能优化方案:批量聚合替代循环查询

当前API因大量循环导致运行缓慢,目前仅完成年度数据的图表计算逻辑,后续还需复用类似代码处理日、月、周维度的数据,重复循环会进一步降低运行效率。原年度图表计算代码如下:

// GRAPH CALCULATION FOR YEAR
let query = '';
graph_data = '';
let startOfYear = MOMENT().startOf('year');
let monthsForYear = [];
let year = [];
// Create an array of dates representing the start of each month in the year
for (let index = 0; index <= 11; index++) {
  const add1Month = MOMENT(startOfYear)
    .add(index, 'month')
    .format('YYYY-MM-DDTHH:mm:SS.000+00:00');
  monthsForYear.push(add1Month);
}
// Get the actual amount for each month
for (let i = 0; i < monthsForYear.length; i++) {
  let j = i + 1;
  let d = await PRISMA.orders.findMany({
    where: {
      created_at: {
        gte: monthsForYear[i],
        lte:
          i === monthsForYear.length - 1 ? endOftheYear_date : monthsForYear[j],
      },
    },
    select: { actual_amount: true },
  });
  // Calculate the total actual amount for the month
  let total = 0;
  d.forEach((el) => {
    total += el.actual_amount;
  });
  year.push(total);
}

// Set the graph data to the calculated amounts
graphDataOfYear = year;

核心优化思路

  • 数据库聚合替代循环查询:将原本N次的数据库查询合并为1次,利用Prisma的groupBy和sum聚合函数直接在数据库层面完成分组求和,大幅减少网络IO开销。
  • 移除手动日期区间生成:通过Prisma的dateTrunc函数自动按时间维度(月/日/周/年)截断日期,无需手动生成每个区间的起止时间。
  • 通用化多维度处理:封装通用函数,仅需传入时间维度参数即可适配所有统计场景,避免重复编写循环逻辑。

优化后的代码示例

年度数据计算优化版

const getYearlyGraphData = async () => {
  const startOfYear = MOMENT().startOf('year').toISOString();
  const endOfYear = MOMENT().endOf('year').toISOString();

  // 一次查询完成所有月份的总额计算
  const monthlyTotals = await PRISMA.orders.groupBy({
    by: ['created_at'],
    where: {
      created_at: {
        gte: startOfYear,
        lte: endOfYear
      }
    },
    _sum: {
      actual_amount: true
    },
    orderBy: {
      created_at: 'asc'
    }
  });

  // 按月份整理数据,确保每个月份都有值(即使为0)
  const graphDataOfYear = Array(12).fill(0);
  monthlyTotals.forEach(item => {
    const monthIndex = MOMENT(item.created_at).month();
    graphDataOfYear[monthIndex] = item._sum.actual_amount || 0;
  });

  return graphDataOfYear;
};

通用多维度处理函数

const getGraphDataByDimension = async (dimension) => {
  const validDimensions = ['year', 'month', 'week', 'day'];
  if (!validDimensions.includes(dimension)) throw new Error('无效的时间维度');

  const startDate = MOMENT().startOf(dimension).toISOString();
  const endDate = MOMENT().endOf(dimension).toISOString();
  let groupByField;
  let totalSlots;

  // 根据维度配置分组字段和总槽数
  switch(dimension) {
    case 'year':
      groupByField = { created_at: { dateTrunc: 'month' } };
      totalSlots = 12;
      break;
    case 'month':
      groupByField = { created_at: { dateTrunc: 'day' } };
      totalSlots = MOMENT().daysInMonth();
      break;
    case 'week':
      groupByField = { created_at: { dateTrunc: 'day' } };
      totalSlots = 7;
      break;
    case 'day':
      groupByField = { created_at: { dateTrunc: 'hour' } };
      totalSlots = 24;
      break;
  }

  // 数据库聚合查询
  const aggregatedData = await PRISMA.orders.groupBy({
    by: [groupByField],
    where: {
      created_at: { gte: startDate, lte: endDate }
    },
    _sum: { actual_amount: true },
    orderBy: { created_at: 'asc' }
  });

  // 填充数据到对应槽位
  const graphData = Array(totalSlots).fill(0);
  aggregatedData.forEach(item => {
    const date = MOMENT(item.created_at);
    let slotIndex;
    switch(dimension) {
      case 'year':
        slotIndex = date.month();
        break;
      case 'month':
        slotIndex = date.date() - 1;
        break;
      case 'week':
        slotIndex = date.day();
        break;
      case 'day':
        slotIndex = date.hour();
        break;
    }
    graphData[slotIndex] = item._sum.actual_amount || 0;
  });

  return graphData;
};

// 使用示例:获取月度数据
// const monthlyGraphData = await getGraphDataByDimension('month');

优化效果说明

  1. 查询次数从N次降为1次:原代码按时间单位循环查询多次,优化后仅需1次数据库请求,减少了大量网络往返时间。
  2. 计算效率提升:数据库的聚合计算比服务端循环求和效率更高,尤其是数据量较大时差异明显。
  3. 代码复用性增强:通用函数支持多维度统计,后续新增维度无需重复编写循环和查询逻辑,维护成本更低。

内容的提问来源于stack exchange,提问作者samtuner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 14:20:59