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; } }