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

如何优化EF Core查询性能?现有代码加载耗时2分钟求改进

EF Core 查询性能优化方案

核心问题分析

原代码最大的性能瓶颈在于提前执行ToList()把全表数据加载到内存后再过滤,这会导致数据库返回大量不必要的数据,大幅增加网络传输和内存处理开销。此外还存在条件判断冗余、字符串处理未下推到数据库执行等问题。

优化后的代码实现

// 构建延迟执行的IQueryable,所有过滤逻辑下推到数据库处理
IQueryable<tablename> query = _context.tablename.AsNoTracking();

if (viewModel.CSku != null)
{
    query = query.Where(x => x.CSku == viewModel.CSku);
    
    if (viewModel.CDesc != null)
    {
        var upperCDesc = viewModel.CDesc.ToUpper();
        query = query.Where(x => EF.Functions.Like(x.CDesc.ToUpper(), $"%{upperCDesc}%"));
    }

    if (viewModel.WCode != null)
    {
        var upperWCode = viewModel.WCode.ToUpper();
        query = query.Where(x => EF.Functions.Like(x.WCode.ToUpper(), $"%{upperWCode}%"));
    }
}
else
{
    // 修复原代码中重复判断Length的冗余逻辑
    bool hasNoPrimaryFilters = viewModel.Length == null 
                               && viewModel.Pattern == null 
                               && viewModel.Prefix == null 
                               && viewModel.Species == null;

    if (!hasNoPrimaryFilters)
    {
        if (viewModel.Length != null)
        {
            var trimmedLength = viewModel.Length.Trim();
            query = query.Where(x => x.Length.Trim() == trimmedLength);
        }

        if (viewModel.Species != null)
        {
            var trimmedSpecies = viewModel.Species.Trim();
            query = query.Where(x => x.Species.Trim() == trimmedSpecies);
        }

        if (viewModel.Pattern != null)
        {
            var trimmedPattern = viewModel.Pattern.Trim();
            query = query.Where(x => x.Pattern.Trim() == trimmedPattern);
        }

        if (viewModel.Prefix != null)
        {
            var trimmedPrefix = viewModel.Prefix.Trim();
            query = query.Where(x => x.Prefix.Trim() == trimmedPrefix);
        }
    }

    if (viewModel.WCode != null)
    {
        var upperWCode = viewModel.WCode.ToUpper();
        query = query.Where(x => EF.Functions.Like(x.WCode.ToUpper(), $"%{upperWCode}%"));
    }
}

// 强制添加分页:避免一次性返回大量数据,根据业务需求调整页大小
// 若业务无需分页可移除,但建议保留以降低前端渲染压力
var paginatedResults = query.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();

return _mapper.Map<IEnumerable<tablenameViewModel>>(paginatedResults).ToList();

额外优化建议

  • 数据库索引优化:为过滤字段(如CSku、CDesc、WCode等)创建索引,针对Contains类模糊查询可考虑创建全文索引,进一步加速数据库查询。
  • 简化字符串操作:如果数据库字段本身是大写存储,可去掉ToUpper();若字段存储时已去除首尾空格,可去掉Trim(),减少不必要的计算。
  • 直接投影映射:使用AutoMapper的ProjectTo方法直接在数据库层面投影需要的字段,减少数据传输量:
    var viewModelQuery = query.ProjectTo<tablenameViewModel>(_mapper.ConfigurationProvider);
    var results = viewModelQuery.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
    return results;
    
  • 监控生成SQL:开启EF Core日志功能查看生成的SQL语句,确认所有过滤逻辑都已下推到数据库,避免意外的客户端内存评估。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 05:05:26