学海无涯

导航

EF Core 查询性能优化

一、IEnumerable 和 IQueryable 的区别

1. IEnumerable (客户端评估)

1.1 是立即查询Sql执行,除了生成首次的 Where 条件之外,之后的查询条件都是在内存中进行,当数据量很大时,性能就会有问题。

2. IQueryable (服务器端评估 推荐)

2.1 它仅仅是一个查询表达式,只有当真正要使用数据时,它才执行Sql

2.2 当有多个Where条件拼接时,最后只生成一条查询语句,大大提升了性能。

2.3 有延迟执行的能力

2.4 适用 于拼接复杂的查询条件

2.5 IQueryable 是一个待查询逻辑,因此可以重复使用

服务器端评估:使用SQL语句在数据库服务器上完成数据筛选(推荐)

客户端评估:把数据首先从服务器加载到内存,然后再进行筛选(返回数据量大时,性能低下)

 以下是服务器端评估(推荐):

生成的条件: WHERE (t.Price >= 1.1000000000000001E0) && (DATEPART(year, t.PubTime) == 2021))
 [HttpGet("price")]
        public async Task<ActionResult<IEnumerable<Book>>> QueryPrice()
        {
            IQueryable<Book> books=_context.Books.Where(m=>m.Price >= 1.1);
            string price = string.Empty;
            books = books.Where(m => m.PubTime.Year == 2021);
            var list = await books.ToListAsync();
            return Ok(list);
        }

  

 SELECT t.Id, t.AuthorName, t.Price, t.PubTime, t.Title
              FROM T_Book AS t
              WHERE (t.Price >= 1.1000000000000001E0) && (DATEPART(year, t.PubTime) == 2021))

 客户端评估:

生成的条件: WHERE [t].[Price] >= 1.1

[HttpGet("price")]
        public async Task<ActionResult<IEnumerable<Book>>> QueryPrice()
        {
            IEnumerable<Book> books=_context.Books.Where(m=>m.Price >= 1.1);
            string price = string.Empty;
            books = books.Where(m => m.PubTime.Year == 2021);
            var list =  books.ToList();
            return Ok(list);
        }

  

 SELECT [t].[Id], [t].[AuthorName], [t].[Price], [t].[PubTime], [t].[Title]
      FROM [T_Book] AS [t]
      WHERE [t].[Price] >= 1.1

 查询时不跟踪数据变更:

[Route("api/v1/[controller]")]
[ApiController]
public class CatalogController : ControllerBase
{
    private readonly CatalogDbContext _context;
    public CatalogController(CatalogDbContext context)
    {
        _context = context;
        _context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
    }
}

  

posted on 2022-10-01 10:28  宁静致远.  阅读(292)  评论(0编辑  收藏  举报