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

带版本化嵌套实体的LINQ查询生成慢SQL问题及性能优化咨询

优化LINQ查询性能的解决方案

你的问题根源在于原LINQ查询每次过滤、排序时都重复执行子查询获取最新的order和term记录,导致生成的SQL多次关联同一张表,而且关联term时逻辑冗余。我们可以模仿你手动SQL的思路,先预获取每个orderHeader对应的最新order,以及每个termHeader对应的最新term,再进行关联查询,这样就能大幅减少表关联次数,提升性能。

具体优化步骤

1. 预定义最新order和term的子查询

先使用窗口函数(ROW_NUMBER())获取每个分组下的最新记录,和你手动SQL的逻辑完全对齐:

// 获取每个orderHeader对应的最新order记录
var latestOrders = _DbContext.order
    .AsNoTracking()
    .Select(o => new {
        o.id,
        o.orderHeaderId,
        o.name,
        o.notes,
        o.termHeaderId,
        o.createdDate,
        RowNum = EF.Functions.RowNumber().Over(
            PartitionBy: o.orderHeaderId,
            OrderBy: o.createdDate descending)
    })
    .Where(o => o.RowNum == 1);

// 获取每个termHeader对应的最新term记录
var latestTerms = _DbContext.term
    .AsNoTracking()
    .Select(t => new {
        t.id,
        t.termHeaderId,
        t.name,
        t.createdDate,
        RowNum = EF.Functions.RowNumber().Over(
            PartitionBy: t.termHeaderId,
            OrderBy: t.createdDate descending)
    })
    .Where(t => t.RowNum == 1);

2. 关联主查询并应用过滤/排序

将orderHeader和预定义的最新order、term关联,后续的过滤和排序都基于关联后的字段,避免重复子查询:

string _word = "%123%";
bool _searchOrderName = true;
bool _searchOrderNotes = true;
bool _searchTermName = true;
int _sort = 0;

// 构建主查询:关联orderHeader、最新order、最新term
var query = from oh in _DbContext.orderHeader.AsNoTracking()
            join lo in latestOrders on oh.id equals lo.orderHeaderId
            join lt in latestTerms on lo.termHeaderId equals lt.termHeaderId
            where oh.isDeleted != true
            select new {
                OrderHeader = oh,
                LatestOrder = lo,
                LatestTerm = lt
            };

// 应用过滤条件
if (_searchOrderName)
{
    query = query.Where(x => EF.Functions.Like(x.LatestOrder.name, _word));
}
if (_searchOrderNotes)
{
    query = query.Where(x => EF.Functions.Like(x.LatestOrder.notes, _word));
}
if (_searchTermName)
{
    query = query.Where(x => EF.Functions.Like(x.LatestTerm.name, _word));
}

// 应用排序
query = _sort switch
{
    // 可根据需求扩展其他排序分支
    _ => query.OrderByDescending(x => x.LatestOrder.name)
};

// 获取总条数(生成的SQL性能与你手动编写的一致)
var totalCount = await query.CountAsync();

优化效果说明

  • 这个LINQ查询生成的SQL会和你手动编写的逻辑完全匹配:只关联order和term各一次,通过窗口函数预取最新记录,彻底解决了原查询中多次子查询、重复关联表的问题。
  • 过滤和排序操作都基于已经关联好的最新记录,不会重复触发子查询,大幅降低数据库的查询开销,计数操作的耗时会降到0.2-0.3秒的水平。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.01 00:07:32