2012-06-19 40 views
1

我有一个ASP.NET MVC2站点通过DbLinq连接到MySQL数据库。在网站上定期完成一组特定的动作,其中包括循环播放几张表中的一组特定记录并更新它们,并在其他一些表中添加一些新记录。DbLinq的对象跟踪性能可以提高吗?

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

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

举一些实际的数字,从最近的测试来看,我有:

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

正如你所看到的,构建和运行SQL查询是由时间量相形见绌花在检查,看看是否存在于实体的引用我们正在更新(如果没有引用,则插入实体,尽管在这种情况下存在所有更新的实体)。虽然我明白为什么会发生这种情况,但为了保持数据的完整性等,这会影响这些定期更新操作的性能。

我看着设置ObjectTrackingEnabled为false,但这使得DataContext是只读的,这对我来说没有用处 - 我的问题是特定于更新的性能。

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

+0

你的逻辑必须阻碍,显示一些代码 - 或者至少给出一个简洁的例子来重现你遇到的问题。我构建了复杂的输入表单,最终使用EF 4.1发送大约18条添加到mysql数据库的记录,如果这样做需要大约5-10秒。 –

+0

您是否长时间使用相同的dataContext,即读取一些行,更新/添加一些行,提交更改,然后使用相同的dataContext重复? – hatchet

+0

@hatchet - 我知道这是针对OP,但是在我的存储库中,每次进行更改时都会保存更改,并且一直使用相同的dataContext。如果他正在打开和关闭一段时间的连接,那可能会对时间有所贡献。但是,在我看来,发生了某种“n!”操作。 –

回答

1

如果使用长寿命DataContexts,在那里你读取数据,修改数据,提交更改,再重复使用相同的DataContext对象,这会产生负面影响性能。一旦DataContext已经实现了一个实体,它就会在DataContext的整个生命周期内将其作为其对象跟踪的一部分保存在内部。随着时间的推移,这种内部缓存会变得很大,在某些情况下,有效地成为你的数据库的很大一部分的内存缓存。这可能会减慢速度,并在SubmitChanges期间导致DataContext更多工作。

的DataContext意味着是短暂的。它的寿命应该是一个工作单位。创建它,将它用于某些东西,然后将其处置。

下面是一些更详细:

Why would reusing a DataContext have a negative performance impact?

,这被某人密切的产品:

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

长寿命使用:DataContext的本身并不覆盖对象 一旦通过查询检索到它们。所以随着时间的流逝,如果检索到的对象频繁更改,它们可能会变陈旧。 ():DataContext可以在 之后使用SubmitChanges(),但必须小心。 SubmitChanges()完成所有 确定您对 对象图所做的所有更改的辛勤工作。它会为您订购CUD操作,并根据每个已更改的 对象的粒度提供乐观并发检查。