为什么重用DataContext会对性能产生负面影响?

MCS*_*MCS 14 c# sql-server datacontext optimization linq-to-sql

经过一个公平 研究和一些错误,我修改了代码,以便它创建了一个新的DataContext每个查询数据库或数据被插入的时间.并且经常查询数据库 - 对于处理的250k个事务中的每一个,在插入事务之前查询数据库以获取客户ID,部门ID和类别.

所以现在我正在尝试优化代码,因为它每秒只处理大约15个事务.我删除了一些无关的查询并添加了一些索引,并将其提高到30 /秒.然后我想,尽管每个人都说DataContext是轻量级的,但是每个事务需要花费4倍的时间来创建一个新的,所以我尝试重用DataContext.我发现,令我惊讶的是,重复使用上下文会导致性能降低到每秒10个事务!

为什么会这样呢?是因为DataContext将实体缓存在内存中,并在查询数据库之前首先搜索其内存列表?因此,例如,如果我正在寻找名为"MCS"的客户的客户ID(主键),并且客户名称列上有聚簇索引,以便数据库查询速度快,则内存中查找会慢吗?

创建/部署如此多的数据库连接是否会降低速度,或者这只是另一种过早的优化?如果确实如此,是否有办法重用DataContext但是它为每个linq-to-sql查询执行实际的数据库查询?

Aar*_*web 15

以下是从MSDN DataContext文档重新使用DataContext不是最佳实践的原因:

DataContext是通过数据库连接映射的所有实体的源.它跟踪您对所有检索到的实体所做的更改,并维护"身份缓存",以确保使用相同的对象实例表示检索多次的实体.

通常,DataContext实例设计为持续一个"工作单元",但是您的应用程序定义该术语.DataContext是轻量级的,创建起来并不昂贵.典型的LINQ to SQL应用程序在方法范围内创建DataContext实例,或者作为表示相关数据库操作的逻辑集的短期类的成员.

如果您为大量查询重复使用DataContext,则性能会因几个原因而降低:

  1. 如果DataContext的内存中身份缓存变得如此之大以至于它必须开始写入页面文件,那么你的性能将受到HD的读取头速度的限制,并且实际上没有理由使用缓存.

  2. 内存中的标识对象越多,每个保存操作所花费的时间就越长.

基本上你正在做的是违反DataContext类的UoW原则.

打开数据库连接确实有一些与之相关的开销,但保持连接打开很长一段时间(这通常也意味着锁定表)比快速打开和关闭它们更不可取.

从MSDN可能会或可能不会帮助您的另一个链接:

如何:重用ADO.NET命令和DataContext之间的连接(LINQ to SQL)