在EF中加载大型集并保存更改

时间:2013-07-26 15:35:53

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

我有实体框架的问题我希望有人可能想要帮助:)

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

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

方法背景(可选阅读):我正在为之工作的客户早已经历过几次这类问题,并且对他们之前发现的解决方案一直不满意。他们得出的结论是,这是最好的方法。所以我现在不是在寻找替代解决方案,而是要找出如何做到这一点,或者相信它不能在合理的时间内完成。

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

1)只需在SQL Server的一个大请求中加载它。在读取时,似乎工作找了一会儿,直到它使用大约1.6 GB的RAM,当我得到OutOfMemoryException时 - 即使有近10 GB的可用RAM。 Exception来自EF。在例外的时候,大约有一半的记录被读过。

2)使用Skip / Take逐个阅读。需要OrderBy,所以我按主表的主键(int,sequential但不是autoincrement)排序。这使得查询更加复杂,最后有15个以上的ORDER BY语句,其中大约5个是实际上是我正在排序的主键副本的列。不知道为什么有那么多副本,但它们就在那里......查询超时 - 当然。

3)从主表中选择所有主键,进行排序。然后取第一个1000并创建一个限制对,其中包含1000个中的最小值和最大值。重复所有1000个组,直到完成为止。现在多次调用查询,检查每对中两个数字之间的主键,一次加载1000。事实证明这是非常缓慢 - 每组1000人需要45秒,这远远不能接受。

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

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

1 个答案:

答案 0 :(得分:0)

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

一次加载500,000行对我来说仍然是一个坏主意,你仍然可能遇到方法#1的其他问题。