Linq查询性能优化求助:6000条车辆数据查询耗时2分钟
代码性能优化方案
你现在的问题是典型的N+1查询性能陷阱:6000条车辆记录,每条都触发2次数据库请求,总共12000次数据库往返,这是导致2分钟耗时的核心原因。优化思路是把多次小查询合并为2次批量查询,然后在内存中完成数据匹配,大幅减少数据库交互次数。
优化后的代码实现
// 1. 提取所有需要处理的车辆ID var vehicleIds = result.Select(v => v.VehicleId).ToList(); // 2. 批量查询所有车辆的有效车牌数量(仅1次数据库请求) var plateCountDict = await _context.PlateVehicles .Where(p => vehicleIds.Contains(p.VehicleId) && p.Status == "Active") .GroupBy(p => p.VehicleId) .Select(g => new { VehicleId = g.Key, Count = g.Count() }) .ToDictionaryAsync(x => x.VehicleId, x => x.Count); // 3. 批量查询所有车辆的保险用途信息(仅1次数据库请求) var policyInfoDict = await _context.Policies .Where(p => vehicleIds.Contains(p.Vehicle_Id)) .ToDictionaryAsync(p => p.Vehicle_Id, p => p.Class ?? string.Empty); // 4. 内存中匹配数据,避免数据库往返 foreach(var vehicle in result) { // 赋值有效车牌数量,无数据则为0 vehicle.PlatesCount = plateCountDict.TryGetValue(vehicle.VehicleId, out var count) ? count : 0; // 检查并赋值保险用途,存在则加入结果集 if(policyInfoDict.TryGetValue(vehicle.VehicleId, out var insuranceUse)) { vehicle.InsuranceUse = insuranceUse; finalOutput.Add(vehicle); } }
额外优化建议
- 添加数据库索引:确保
PlateVehicle.VehicleId、PlateVehicle.Status、Policies.Vehicle_Id这几个字段有组合索引或单独索引,让批量查询的速度更快。 - 初始查询直接关联(更优):如果
result本身是从数据库查询得到的,可以直接在初始查询时关联两个表,一步完成统计和数据获取,彻底避免循环:
var finalOutput = await _context.Vehicles // 替换成你原来获取result的查询条件 .Where(/* 你的原始查询条件 */) .Select(v => new { Vehicle = v, PlatesCount = _context.PlateVehicles.Count(p => p.VehicleId == v.VehicleId && p.Status == "Active"), InsuranceUse = _context.Policies.Where(p => p.Vehicle_Id == v.VehicleId).Select(p => p.Class ?? string.Empty).FirstOrDefault() }) .Where(x => !string.IsNullOrEmpty(x.InsuranceUse)) .Select(x => { x.Vehicle.PlatesCount = x.PlatesCount; x.Vehicle.InsuranceUse = x.InsuranceUse; return x.Vehicle; }) .ToListAsync();
内容的提问来源于stack exchange,提问作者sri
相关产品推荐
相关产品推荐

