【问题标题】:Loading large sets in EF and saving changes在 EF 中加载大型集并保存更改
【发布时间】:2013-07-26 15:35:53
【问题描述】:

我在使用 Entity Framework 时遇到问题,希望有人能提供帮助:)

我正在尝试实现的功能:我的应用程序应该能够从第三方应用程序获取 XML 转储,查看数据并与应用程序数据库中的内容进行比较并更新任何依赖于非平凡标准的实体,该标准基于实体的 XML 版本和 DB 版本。

方法:将所有数据加载到内存中(EF for DB)并在内存中进行所有比较并将更新写回DB。

方法的背景(可选阅读):我工作的客户之前曾多次遇到过此类问题,并且从未对他们之前找到的解决方案感到满意。他们得出的结论是,这是最好的方法。因此,我目前不是在寻找替代解决方案,而是要找出如何做到这一点,或者确信无法在合理的时间内完成。

我的问题:将 XML 加载到内存中没有问题,从数据库加载更是如此。问题的核心是数据存储在 8 个有连接的表中,主表有近 500 000 行。结果是返回大量数据的复杂查询。我尝试了几种方法:

1) 只需从 SQL Server 的一个大请求中加载所有内容。似乎在阅读时找到了一段时间,直到它使用大约 1.6 GB 的 RAM,当我得到 OutOfMemoryException - 即使有近 10 GB 的可用 RAM。异常来自 EF 内部。在异常发生时,大约一半的记录已被读取。

2) 使用 Skip/Take 逐段阅读。需要 OrderBy,所以我按主表的主键排序(int,顺序但不是自动增量)。这使查询变得更加复杂,最后有 15 多个 ORDER BY 语句,其中大约 5 个是实际作为我排序依据的主键副本的列。不知道为什么会有这么多副本,但它们就在那里……当然查询超时了。

3) 从主表中选择所有主键,排序。然后取前 1000 个并创建一个包含这 1000 个中最小和最大的限制对。对所有 1000 个组重复直到完成。现在多次调用查询,检查每对中两个数字之间的主键,以一次加载集合 1000。结果证明这非常慢——每组 1000 人需要 45 秒,这远远不能接受。

选项 1 似乎最接近工作,但 EF 内部似乎存在内存限制。有可能以某种方式调整它吗?

我正考虑放弃 EF 来完成这项任务(即使它在其他地方的整个应用程序中都使用过),但我想我会先给你一个问题 ;-)

【问题讨论】:

  • 应用程序是否编译为 32 位应用程序?您将有 2 GB 进程内存的自然限制,由于可能存在内存碎片,这通常不能完全使用。使用 64 位应用程序和操作系统,您将在进程空间中拥有更多可用内存,仍然减去可能的碎片,但可能已经足够了。

标签: .net sql-server performance entity-framework


【解决方案1】:

大多数 Visual Studio 项目模板的默认平台目标是 x86。您需要将项目更改为以 x64 或任何 CPU 为目标,以便能够使用超过 2GB 的内存。为此,请转到项目的属性,构建选项卡,选择平台目标下的任何 CPU。

虽然一次加载 500,000 行在我看来仍然是个坏主意,但您仍然可能会遇到方法 #1 的其他问题。

【讨论】:

  • 大多数时候,Stack Overflow 是一个很好的地方,可以提出问题并从中获得信息丰富的答案 - 其他时候,当您阅读显而易见的内容时,它是一个意识到自己是个白痴的地方回答...感谢您让我觉得自己像个白痴-它为我节省了很多时间;-)
猜你喜欢
  • 2011-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-09
  • 2021-10-18
  • 2013-08-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多