首页 > 解决方案 > 为什么第一个请求需要更多时间?

问题描述

今天在一些实验中,我注意到一件有趣的事情:

var dbContextOptionsBuilder = new DbContextOptionsBuilder<MyContext>();
dbContextOptionsBuilder.UseSqlServer(@"Data Source=LAPTOP-HBBAKRHO\SQLEXPRESS;Initial Catalog=myDb;Integrated Security=True");
var context = new MyContext(dbContextOptionsBuilder.Options);

Stopwatch stopWatch;

stopWatch = Stopwatch.StartNew();
context.Projects.AsNoTracking().SingleOrDefault(p => p.Id.Equals(12345));
stopWatch.Stop();
Debug.WriteLine($"AsNoTracking().SingleOrDefaultAsync, by ID: {stopWatch.ElapsedMilliseconds}");

stopWatch = Stopwatch.StartNew();
context.Projects.AsNoTracking().SingleOrDefault(p => p.Id.Equals(12345));
stopWatch.Stop();
Debug.WriteLine($"AsNoTracking().SingleOrDefaultAsync, by ID: {stopWatch.ElapsedMilliseconds}");

stopWatch = Stopwatch.StartNew();
context.Projects.AsNoTracking().SingleOrDefault(p => p.Id.Equals(12345));
stopWatch.Stop();
Debug.WriteLine($"AsNoTracking().SingleOrDefaultAsync, by ID: {stopWatch.ElapsedMilliseconds}");

// CLOSE.
context.Dispose();

结果:


如您所见,第一个请求总是需要更多时间。为什么会这样?

我认为 ORM 为每个请求打开/关闭数据库连接,也许不是这样,EF Core仅第一次打开连接并将其用于所有下一个请求,直到DbContext处理掉?

标签: c#sql-server.net-coreentity-framework-coreef-core-2.1

解决方案


您每次都通过相同的参数从同一个上下文实例中获取数据,因此第二个和第三个获取请求根本不会发送到 SQL Server。EF 拥有其从数据库加载的所有实体的一级缓存。这就是为什么第二次和第三次要快得多。如果将第二个查询的参数 12345 更改为任何其他参数,它会比第一个更快,但不会那么快,因为它会从服务器请求数据。

我建议您阅读有关 EF 执行和性能的这些主题:

以正确的方式管理 ef

查询计划缓存故事


推荐阅读