7

我们有一组相当大的相关表,每个表有超过 3500 万条相关记录。我需要创建几个 WCF 方法,它们将使用一些参数(数据范围、类型代码等)查询数据库并返回相关的结果集(从 10 到 10,000 条记录)。

该公司在 EF 4.0 上进行了标准化,但对 4.X 开放。我可能会提出迁移到 5.0 的论据,但可能性较小。

使用实体处理如此大量记录的最佳方法是什么?我应该创建一组存储过程并从实体调用它们还是我可以在实体中做些什么?

我对数据库没有任何控制权,因此我无法拆分表或创建一些物化视图或分区表。

非常感谢任何输入/想法/建议。

4

3 回答 3

8

在我的工作中,我遇到了类似的情况。我们有一个包含许多表的数据库,其中大多数每个表包含大约 7 到 1000 万条记录。我们使用实体框架来显示数据,但页面显示速度似乎很慢(比如 90 到 100 秒)。甚至网格上的排序也需要时间。我的任务是看它是否可以优化。并且在对其进行分析(ANTS 分析器)之后,我能够对其进行优化(不到 7 秒)。

所以答案是肯定的,实体框架可以处理大量记录(以百万计),但必须小心

  1. 了解仅在需要实际记录时才调用数据库。所有操作都只是用来进行查询(SQL),所以尽量只获取一条数据而不是请求大量记录。尽可能修剪 fetch 大小
  2. 是的,你不应该,你必须使用存储过程并将它们导入你的模型,并为它们导入函数。也可以直接调用它们 ExecuteStoreCommand()、ExecuteStoreQuery<>()。同样适用于函数和视图,但 EF 有一种非常奇怪的调用函数“SELECT dbo.blah(@id)”的方式。
  3. EF 在必须填充具有较深层次结构的实体时执行较慢。对层次结构较深的实体要格外小心。
  4. 有时,当您请求记录并且不需要修改它们时,您应该告诉 EF 不要查看属性更改 (AutoDetectChanges)。这样记录检索要快得多
  5. 数据库的索引很好,但在 EF 的情况下它变得非常重要。您用于检索和排序的列应该被正确索引。
  6. 当您的模型很大时,VS2010/VS2012 模型设计师会变得非常疯狂。所以把你的模型分成中型模型。存在一个限制,即来自不同模型的实体不能共享,即使它们可能指向数据库中的同一个表。
  7. 当您必须在不同位置对同一实体进行更改时,请尝试通过传递来使用同一实体并仅发送一次更改,而不是每个人都获取一个新的片段,进行更改并存储它(真正的性能增益提示)。
  8. 当您只需要一两列中的信息时,尽量不要获取完整的实体。你可以直接执行你的 sql 或者有一个迷你实体。您可能还需要在应用程序中缓存一些常用数据。
  9. 交易很慢。小心他们。

如果你牢记这些事情,EF 应该提供与普通 ADO.NET 几乎相似的性能,如果不一样的话。

于 2013-10-11T07:21:20.150 回答
4

我对 EF4.1 的经验,代码优先:如果您只需要读取记录(即您不会将它们写回),您将通过为您的上下文打开更改跟踪来获得性能提升:

yourDbContext.Configuration.AutoDetectChangesEnabled = false;

在加载任何实体之前执行此操作。如果您需要更新加载的记录,您可以随时调用

yourDbContext.ChangeTracker.DetectChanges();

在调用 SaveChanges() 之前。

于 2013-01-23T19:18:37.147 回答
0

当我听到类似这样的声明时:“公司在 EF4 或 EF5 或其他方面进行了标准化”这让我脊背发凉。

这相当于汽车租赁说“我们已经为我们的整个车队标准化了单一车型”。

或者木匠说“我已经将凿子标准化为我的整个工具包。我不会有锯子、钻头等......”

有一种东西叫做正确的工具来做正确的工作 这句话只是强调了负责制定关键软件架构决策的人对软件架构一无所知。

如果您正在处理超过 100K 的记录并且数据模型很复杂(即非平凡的),也许 EF6 不是最佳选择。EF6 基于动态反射的概念,与 Castle Project Active Record 有类似的设计模式

您是否需要将所有 100K 记录加载到内存中并对这些记录执行操作?如果是的话,问问你自己你真的需要这样做吗,为什么在 100K 记录中执行存储过程不能达到同样的效果。做一些分析,看看实际的数据使用模式是什么。也许用户执行的搜索返回 10 万条记录,但他们只浏览前 200 条记录。例如谷歌搜索,几乎没有人超过数百万搜索结果的第 3 页。

如果答案仍然是肯定的,您需要将所有 100K 记录加载到内存中并执行操作。然后,也许您需要考虑其他一些东西,例如使用轻量级对象通过缓存自定义构建的写入。也许延迟加载嵌套对象的动态对象指针。等等......我使用类似这样的东西的一个例子是电子商务网站的大型产品目录,其中对目录执行了大量搜索。为什么是为了提供自定义行为,例如提前退出搜索,以及使用预编译的正则表达式进行正则表达式通配符搜索,或自定义 Hashtable 索引到产品目录中。

对于这个问题,没有一个万能的答案。这一切都取决于数据使用场景以及应用程序如何处理数据。想想大猩猩对鲨鱼谁会赢?这一切都取决于环境和背景。

也许 EF6 非常适合从动态反射中受益的部分,而 NetTiers 更适合需要静态反射和可扩展 ORM 的另一部分。而低级 ADO 可能最适合极高性能的作品。

于 2017-01-30T22:13:32.547 回答