为什么创建新的 DbContext 比创建依赖注入的数据库上下文慢?



我最近确定,在 .NET Core 中使用依赖注入的 DbContext 并使用异步等待调用(而不是每次要访问数据库时都创建新的 DbContext)不会显著提高性能。

但现在我需要知道为什么。

我在 .NET Core 1.1 API 服务(控制器正在调用)中使用 System.Diagnostics.Stopwatch 进行了更精细的测试,其中我仅在访问数据库时运行秒表。结果令人惊讶。

使用标准依赖关系注入上下文和异步/等待调用时:

var task1 = _InjectedDbContext.Table1.FirstOrDefaultAsync(p => p.Id == SomeId);
var task2 = _InjectedDbContext.Table2.Where(u => u.AnotherId == SomeOtherId).ToListAsync();
(var result1, var result2) = await (task1, task2).WhenAll();

每个 DbContext 查询花费的时间明显少于 100 毫秒。

但是,使用此方法时:

using (var context = new DbContext(_InjectedContextOptions.Options))
{
var task1 = context.Table1.FirstOrDefaultAsync(p => p.Id == SomeId);
var task2 = context.Table2.Where(u => u.AnotherId == SomeOtherId).ToListAsync();
(var result1, var result2) = await (task1, task2).WhenAll();
}

每个 DbContext 查询需要 100-230 毫秒的时间。

仅供参考,这是我在启动.cs配置服务中用于 DI 设置的代码:

var connection = Configuration.GetConnectionString("mydb");
services.AddDbContext<MyDbContext>(options => options.UseSqlServer(connection));

这是我的代码,每当我创建新的 DbContext 时,都会将 DbContextOptions 作为单例提供:

var dbContextOptions = new DbContextOptionsBuilder<MyDbContext>();        
dbContextOptions.UseSqlServer(Configuration.GetConnectionString("MyDb"));
services.AddSingleton(dbContextOptions);

我还确定滞后不是由简单地在 using 语句中创建 DbContext 引起的(这是一个非常快的操作)。这是怎么回事?是每次都尝试重新连接到数据库还是其他什么?

您正在使用 AddDbContext 方法,用于您在第一个方案中使用的 DbContext,该方法将 DbContext 作为 Scoped 添加到服务中(如果我没记错的话)。由于优化,DbContext 可能在添加服务后立即初始化(此处不确定)。对于第二种情况,您将创建一个新的 DbContext。除了创建 DbContext 之外,还有一些其他的事情需要完成。

摘自这篇文章,这里有一些提示来"热身"你的环境:

  1. 使用缓存的数据库模型存储
  2. 生成预编译视图
  3. 使用 n 代生成实体框架的预编译版本以避免抖动

上面的提示表明,使用 DbContext 不仅仅是"仅仅"更新一个并开始查询。

相关内容

  • 没有找到相关文章

最新更新