1

我有一个通过 DbLinq 连接到 MySQL 数据库的 ASP.NET MVC2 站点。网站上会定期执行一组特定的操作,其中包括循环访问几个表中的一组特定记录并更新它们,以及在其他一些表中添加一些新记录。

我一直在用一组中等大小的数据进行测试。在我现在的特定测试集中,在更新时它最终会插入 44 个新行并更新 81 个其他行。但是我对 SubmitChanges() 的调用最终需要很长时间 - 大约 3-4 分钟,这似乎需要很长时间才能推动(我认为是)对数据库进行相对少量的更改。

我最终做了一些简单的分析,我发现问题似乎不在于在数据库上执行查询,甚至不在于构建查询。大多数时间似乎都被 UpdateEntity 内部对 AllTrackedEntities.ContainsReference() 的调用占用了。

为了给出一些实际数字,从最近的一次测试中我得到了:

  • SubmitChangesImpl 中的时间:204884 毫秒
    • UpdateEntity 中的时间:200908 毫秒
      • ContainsReference 中的时间:148173 毫秒
      • QueryBuilder.GetUpdateQuery 中的时间:685 毫秒
      • QueryRunner.Update 中的时间:28 毫秒
      • UpdateReferencedObjects 中的时间:49958 毫秒

如您所见,构建和运行 SQL 查询与检查是否存在对我们正在更新的实体的引用相比相形见绌(如果没有引用,则插入实体,尽管在这种情况下所有的更新实体存在)。虽然我理解为什么会发生这种情况,为了维护数据完整性等等,但这正在扼杀这些定期更新操作的性能。

我查看了将 ObjectTrackingEnabled 设置为 false,但这使得 DataContext 是只读的,这对我没有用 - 我的问题特别是更新的性能。

有什么办法可以提高更新的性能吗?就尝试在一次提交中推送 40-50 次插入和 80 多次更新而言,我是否以不太理想的方式使用 DbLinq?如果是这样,有没有更好的方法来解决这个问题?

4

1 回答 1

1

如果您使用长期存在的 DataContexts,您在其中读取数据、修改数据、提交更改,然后重复使用相同的 DataContext 对象,这可能会对性能产生负面影响。一旦 DataContext 实体化了一个实体,它就会在 DataContext 的整个生命周期内将其保留在内部,作为其对象跟踪的一部分。随着时间的推移,这个内部缓存会变得很大,在某些情况下,它实际上会成为数据库大部分的内存缓存。这会减慢速度,并在 SubmitChanges 期间为 DataContext 带来更多工作。

DataContext 是短暂的。它的生命周期应该是一个工作单元。创建它,将其用于某事,然后处置它。

这里有一些更详细的信息:

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

这是由接近产品的人提出的:

http://blogs.msdn.com/b/dinesh.kulkarni/archive/2008/04/27/lifetime-of-a-linq-to-sql-datacontext.aspx

长期使用:一旦您通过查询检索对象,DataContext 本身不会覆盖它们。因此,随着时间的流逝,如果经常更改检索到的对象,它们可能会变得陈旧。

SubmitChanges() 之后的生活:DataContext 可以在 SubmitChanges() 之后使用,但必须小心。SubmitChanges() 完成所有艰苦的工作,找出您对对象图所做的所有更改。它为您订购 CUD 操作,并在每个更改的对象的粒度上提供乐观并发检查。

于 2012-06-19T20:21:22.043 回答