【发布时间】:2012-06-19 19:22:49
【问题描述】:
我有一个通过 DbLinq 连接到 MySQL 数据库的 ASP.NET MVC2 站点。网站上会定期执行一组特定的操作,其中包括遍历几个表中的一组特定记录并更新它们,以及在其他一些表中添加一些新记录。
我一直在用一组中等规模的数据进行测试。在我现在的特定测试集中,在更新时它最终会插入 44 条新行并更新 81 条其他行。但是我对 SubmitChanges() 的调用最终花费了很长时间 - 大约 3-4 分钟,这似乎需要很长时间才能推动(我认为是)对数据库进行相对少量的更改。
我最终做了一些简单的分析,我发现问题似乎不在于在数据库上执行查询,甚至不在于构建查询。大多数时间似乎都被 UpdateEntity 内部对 AllTrackedEntities.ContainsReference() 的调用占用了。
为了给出一些实际的数字,我最近的一次测试运行:
- SubmitChangesImpl 中的时间:204884 毫秒
- UpdateEntity 中的时间:200908 毫秒
- ContainsReference 中的时间:148173 毫秒
- QueryBuilder.GetUpdateQuery 中的时间:685 毫秒
- QueryRunner 中的时间。更新:28 毫秒
- UpdateReferencedObjects 中的时间:49958 毫秒
- UpdateEntity 中的时间:200908 毫秒
如您所见,构建和运行 SQL 查询与检查是否存在对我们正在更新的实体的引用相比相形见绌(如果没有引用,则插入实体,尽管在这种情况下所有更新的实体都存在)。虽然我理解为什么会发生这种情况,为了维护数据完整性等等,但这会破坏这些定期更新操作的性能。
我查看了将 ObjectTrackingEnabled 设置为 false,但这使得 DataContext 是只读的,这对我没有用 - 我的问题特别是更新的性能。
有什么可以提高更新性能的方法吗?就尝试在一次提交中推送 40-50 次插入和 80 多次更新而言,我是否以不太理想的方式使用 DbLinq?如果是这样,有没有更好的方法来解决这个问题?
【问题讨论】:
-
你的逻辑一定会妨碍你,显示一些代码 - 或者至少给出一个简洁的例子来重现你遇到的问题。我构建了复杂的输入表单,最终使用 EF 4.1 发送大约 18 条记录以添加到 mysql 数据库中,如果那样的话,大约需要 5 - 10 秒。
-
您是否长期使用相同的dataContext,即读取一些行,更新/添加一些行,提交更改,然后使用相同的dataContext重复?
-
@hatchet - 我知道这是针对 OP 的,但在我的存储库中,每次进行更改时我都会保存更改,并始终使用相同的 dataContext。如果他多次打开和关闭连接,这可能会增加时间。但是,在我看来,发生了某种
n!操作。 -
我对 linq to Sql 的理解是,实体一旦物化,就保留在上下文的内部缓存中。对于长期存在的上下文,这可能会积累大量可能陈旧的数据,并为其内部更改跟踪带来更多工作。 DataContext 的目的是短暂的......使用它并折腾它。它们的建造成本很低。
-
@hatchet 是绝对正确的,我的问题在我的 DataContext 上的生命周期太长了。我曾认为,由于所有操作都构成一个逻辑事务,我最好使用一个 DataContext,最后使用一个 SubmitChanges。我放入了许多 SubmitChanges 进行测试,然后很明显 - 每个后续的 SubmitChanges 都比前一个花费更长的时间,即使它做的“工作”比以前少。将其分解为单独的、短暂的 DataContext 就可以了。如果您想将其添加为答案,我会尽快接受。