实体,处理大量记录(> 3500万)

7
我们有一个非常大的相关表集,每个表都有超过3500万条记录。我需要创建一些WCF方法,用一些参数(数据范围、类型代码等)查询数据库,并返回相关结果集(从10到10000条记录)。公司标准化使用EF 4.0,但也可以使用4.X版本。我可能能够说服他们迁移到5.0,但可能性较小。
如何处理这么多记录是使用Entity的最佳方法?我应该创建一组存储过程并从Entity中调用它们,还是有什么我可以在Entity内部做的吗?
我没有控制数据库,因此无法拆分表或创建一些材料化视图或分区表。
非常感谢您的任何意见/想法/建议。

你打算如何处理返回的10000个实体? - Pawel
3个回答

8
在我的工作中,我遇到了相似的情况。我们有一个包含很多表的数据库,其中大部分表每个都包含大约7到10万条记录。我们使用Entity framework来显示数据,但是页面显示非常缓慢(大约需要90到100秒)。即使是在网格上进行排序也需要时间。我被任务去看看它是否能够被优化或不。最终,在对其进行分析(ANTS profiler)后,我成功地进行了优化(在7秒内)。
所以答案是:Entity framework可以处理大量记录(数百万),但必须小心谨慎。
1. 理解只有在实际需要时才会调用数据库中的记录。所有操作仅用于生成查询(SQL),因此尽可能获取少量数据而不是请求大量记录。尽量减少检索大小 2. 是的,你应该(必须)使用存储过程并将其导入到模型中,并为它们创建函数导入。您还可以直接调用它们ExecuteStoreCommand(),ExecuteStoreQuerylt;gt;()。同样适用于函数和视图,但是EF调用函数的方式非常奇怪“SELECT dbo.blah(@ id)”。 3. 当需要填充具有深层次结构的实体时,EF的性能会降低。对带有深层次结构的实体要非常小心。 4. 有时,当您请求记录并且不需要修改它们时,应告诉EF不要监视属性更改(AutoDetectChanges)。这样记录检索速度会更快 5. 数据库索引很好,但在EF的情况下非常重要。用于检索和排序的列应正确索引。 6. 当您的模型很大时,VS2010 / VS2012模型设计器变得非常疯狂。因此,将您的模型分解成中等大小的模型。存在一个限制,即来自不同模型的实体不能共享,即使它们指向数据库中的相同表。 7. 当您必须在不同位置对同一实体进行更改时,请尝试使用相同的实体通过传递它并仅发送更改,而不是每个人都获取新鲜的部分,进行更改并存储它(真正的性能提升技巧)。 8. 当您只需要一个或两个列的信息时,请尽量不要获取完整实体。您可以直接执行sql或拥有迷你实体。您可能还需要在应用程序中缓存某些频繁使用的数据。 9. 事务很慢。要小心。
如果您铭记这些事情,EF应该会给出几乎与纯ADO.NET相似的性能,如果没有更好。

4

我的EF4.1,code first经验:如果你只需要读取记录(即不写回),通过关闭上下文的更改跟踪,可以获得性能提升:

yourDbContext.Configuration.AutoDetectChangesEnabled = false;

在加载任何实体之前,请执行此操作。如果您需要更新已加载的记录,则始终可以调用以下函数:
yourDbContext.ChangeTracker.DetectChanges();

调用 SaveChanges() 之前。

0
每当我听到像“公司已经标准化使用EF4或EF5,或者其他什么”的说法时,我就会感到寒意袭人。
这相当于一家汽车租赁公司说:“我们已经为整个车队标准化了一种汽车型号。”
或者一个木匠说:“我已经将凿子作为我的整个工具箱的标准。我不会使用锯子、钻头等等。”
有一种叫做正确的工具用于正确的工作的道理。这种说法只能说明负责制定关键软件架构决策的人对软件架构一无所知。
如果你正在处理超过100K条记录,并且数据模型很复杂(即非平凡的),那么也许EF6不是最佳选择。
EF6基于动态反射的概念,并具有类似于Castle Project Active Record的设计模式。
你需要将所有的100K条记录加载到内存中并对其执行操作吗?如果是,请问自己是否真的需要这样做,为什么不能在100K条记录上执行存储过程来实现同样的效果。进行一些分析,看看实际的数据使用模式是什么。也许用户执行搜索返回了100K条记录,但他们只浏览了前200条。例如谷歌搜索,几乎没有人会翻过数百万条搜索结果的第三页。
如果答案仍然是肯定的,那么您需要将所有的10万条记录加载到内存中并执行操作。然后,也许您需要考虑其他一些东西,比如使用轻量级对象构建的自定义写入缓存。也许是惰性加载嵌套对象指针等等。我使用这样的一个实例是大型电子商务网站的产品目录,其中对目录执行非常大量的搜索。为什么呢?为了提供自定义行为,例如早期退出搜索,并使用预编译的正则表达式进行正则表达式通配符搜索,或者使用自定义哈希表索引到产品目录中。
对于这个问题,没有一个适合所有情况的答案。这完全取决于数据使用场景以及应用程序如何处理数据。考虑大猩猩和鲨鱼谁会赢?这完全取决于环境和上下文。
也许EF6对于需要动态反射的某个部分来说是完美的,而NetTiers对于需要静态反射和可扩展ORM的另一个部分来说更好。而低级别的ADO可能最适合极高性能的部分。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接