From f771abb6bf833ba04809b9581e158bf0c2be4ea2 Mon Sep 17 00:00:00 2001
From: ssss <111@qq.com>
Date: Fri, 3 Jul 2026 14:28:35 +0800
Subject: [PATCH] =?UTF-8?q?perf(stats):=20=E4=BD=BF=E7=94=A8=E6=95=B0?=
=?UTF-8?q?=E6=8D=AE=E5=BA=93=E7=AB=AF=E8=81=9A=E5=90=88=E4=BC=98=E5=8C=96?=
=?UTF-8?q?=E7=BB=9F=E8=AE=A1=E6=9F=A5=E8=AF=A2?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../Services/StatsService.cs | 112 ++++++++++--------
1 file changed, 63 insertions(+), 49 deletions(-)
diff --git a/src/WCTDataMiner.Core/Services/StatsService.cs b/src/WCTDataMiner.Core/Services/StatsService.cs
index 8e12b2e..9ad46cf 100644
--- a/src/WCTDataMiner.Core/Services/StatsService.cs
+++ b/src/WCTDataMiner.Core/Services/StatsService.cs
@@ -1,106 +1,120 @@
using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.Logging;
using WCTDataMiner.Core.Data;
using WCTDataMiner.Core.Models;
namespace WCTDataMiner.Core.Services;
///
-/// 统计查询服务
+/// 统计查询服务 - 使用数据库端聚合优化内存效率
///
public class StatsService
{
private readonly WctMinerDbContext _context;
+ private readonly ILogger _logger;
- public StatsService(WctMinerDbContext context)
+ public StatsService(WctMinerDbContext context, ILogger logger)
{
_context = context;
+ _logger = logger;
}
///
- /// 获取整体统计摘要
+ /// 获取整体统计摘要(并行查询优化)
///
public async Task GetSummaryAsync()
{
- var scenarioCount = await _context.TestScenarios.CountAsync();
- var qfodCount = await _context.QfodRecords.CountAsync();
- var plossCount = await _context.PlossRecords.CountAsync();
- var panelCount = await _context.TxPanels.CountAsync();
- var hardwareCount = await _context.TxHardwares.CountAsync();
- var softwareCount = await _context.TxSoftwares.CountAsync();
- var rxTypeCount = await _context.RxTypes.CountAsync();
+ // 使用 Task.WhenAll 并行执行多个查询
+ var tasks = new[]
+ {
+ _context.TestScenarios.CountAsync(),
+ _context.QfodRecords.CountAsync(),
+ _context.PlossRecords.CountAsync(),
+ _context.TxPanels.CountAsync(),
+ _context.TxHardwares.CountAsync(),
+ _context.TxSoftwares.CountAsync(),
+ _context.RxTypes.CountAsync()
+ };
- return new StatsSummary(
- scenarioCount, qfodCount, plossCount,
- panelCount, hardwareCount, softwareCount, rxTypeCount
+ var results = await Task.WhenAll(tasks);
+
+ var summary = new StatsSummary(
+ results[0], results[1], results[2],
+ results[3], results[4], results[5], results[6]
);
+
+ _logger.LogDebug("统计摘要: Scenarios={ScenarioCount}, Qfod={QfodCount}, Ploss={PlossCount}",
+ summary.ScenarioCount, summary.QfodCount, summary.PlossCount);
+
+ return summary;
}
///
- /// 按FOD类型统计Qfod记录
+ /// 按FOD类型统计Qfod记录(数据库端聚合)
///
public async Task> GetStatsByFodTypeAsync()
{
- // 先加载到内存再分组(EF Core 对 GroupBy + 自定义类型有限制)
- var data = await _context.QfodRecords
- .Select(r => r.FodType)
- .ToListAsync();
-
- return data
- .GroupBy(f => f)
+ // 使用数据库端 GroupBy
+ var stats = await _context.QfodRecords
+ .GroupBy(r => r.FodType)
.Select(g => new FodTypeStats(g.Key, g.Count()))
.OrderBy(s => s.FodType)
- .ToList();
+ .ToListAsync();
+
+ _logger.LogDebug("按 FOD 类型统计完成: {Count} 种类型", stats.Count);
+ return stats;
}
///
- /// 按面板类型统计
+ /// 按面板类型统计(数据库端聚合 - 使用维度表反向统计)
///
public async Task> GetStatsByPanelAsync()
{
- var data = await _context.TestScenarios
- .Include(s => s.TxPanel)
- .Select(s => s.TxPanel.Name)
+ // 方式: 使用维度表反向统计(更高效)
+ var stats = await _context.TxPanels
+ .Select(p => new DimensionStats(
+ p.Name,
+ p.TestScenarios.Count()
+ ))
+ .OrderByDescending(s => s.Count)
.ToListAsync();
- return data
- .GroupBy(n => n)
- .Select(g => new DimensionStats(g.Key, g.Count()))
- .OrderByDescending(s => s.Count)
- .ToList();
+ _logger.LogDebug("按面板类型统计完成: {Count} 种面板", stats.Count);
+ return stats;
}
///
- /// 按硬件版本统计
+ /// 按硬件版本统计(数据库端聚合)
///
public async Task> GetStatsByHardwareAsync()
{
- var data = await _context.TestScenarios
- .Include(s => s.TxHardware)
- .Select(s => s.TxHardware.Version)
+ var stats = await _context.TxHardwares
+ .Select(h => new DimensionStats(
+ h.Version,
+ h.TestScenarios.Count()
+ ))
+ .OrderByDescending(s => s.Count)
.ToListAsync();
- return data
- .GroupBy(v => v)
- .Select(g => new DimensionStats(g.Key, g.Count()))
- .OrderByDescending(s => s.Count)
- .ToList();
+ _logger.LogDebug("按硬件版本统计完成: {Count} 种版本", stats.Count);
+ return stats;
}
///
- /// 按RX类型统计
+ /// 按RX类型统计(数据库端聚合)
///
public async Task> GetStatsByRxTypeAsync()
{
- var data = await _context.TestScenarios
- .Include(s => s.RxType)
- .Select(s => s.RxType.Name)
+ var stats = await _context.RxTypes
+ .Select(r => new DimensionStats(
+ r.Name,
+ r.TestScenarios.Count()
+ ))
+ .OrderByDescending(s => s.Count)
.ToListAsync();
- return data
- .GroupBy(n => n)
- .Select(g => new DimensionStats(g.Key, g.Count()))
- .OrderByDescending(s => s.Count)
- .ToList();
+ _logger.LogDebug("按 RX 类型统计完成: {Count} 种类型", stats.Count);
+ return stats;
}
}