【问题标题】:What is the fastest way to sort an EF-to-Linq query?对 EF-to-Linq 查询进行排序的最快方法是什么?
【发布时间】:2015-10-21 06:25:49
【问题描述】:

使用实体框架,理论上哪个更快:

// (1) sort then select/project
// in db, for entire table
var results = someQuery
              .OrderBy(q => q.FieldA)
              .Select(q => new { q.FieldA, q.FieldB })
              .ToDictionary(q => q.FieldA, q => q.FieldB);

// (2) select/project then sort
// in db, on a smaller data set
var results = someQuery
              .Select(q => new { q.FieldA, q.FieldB })
              .OrderBy(q => q.FieldA)
              .ToDictionary(q => q.FieldA, q => q.FieldB);

// (3) select/project then materialize then sort
// in object space
var results = someQuery
              .Select(q => new { q.FieldA, q.FieldB })
              .ToDictionary(q => q.FieldA, q => q.FieldB)
              .OrderBy(q => q.FieldA);  // -> this won't compile, but you get the question

我不是 SQL 专家,但直觉上似乎 2 比 1 快……对吗?这与 3 相比如何,因为根据我的 EF 经验,在 db 上完成几乎所有事情都会更快。

PS 我的环境中没有性能工具,不知道如何测试,因此提出了问题。

【问题讨论】:

  • 由于 Linq 使用延迟执行,1 和 2 是等价的。在 3 中,您正在使用 Linq to Objects 进行排序(因为您首先调用了ToDictionary(),而您不再处于IQueryable 的范围内),并且排序将在内存中完成,不会有ORDER BY发射。
  • 您可以使用计时器对其进行测试。你为什么要订购字典?前两个是不同的类型,然后是第三个......
  • @hbob,没办法说。它取决于许多因素(数据库索引、表结构等等)。如果您要询问具体案例,则必须自己进行测试。
  • 您似乎相信某些编码模式将始终产生“最佳性能”,并且您将能够找到这些模式并在所有情况下盲目地应用它们。不幸的是,这不是大多数代码的工作方式。最好先设定性能目标,然后编写清晰、可理解的代码,而忽略目标。然后测量性能。只有当代码表现不佳时,您才应该考虑破坏清晰易懂的代码。此时,您尝试变化并再次测量它们,以找出在当前情况下最有效的方法。
  • 不,我不认识你,但我知道在大多数开发人员的职业生涯中都会出现这样一个阶段,他们认为诸如“这些选项中哪个更快?”之类的问题。可以有一个直截了当的答案,当现实几乎总是“这取决于,你需要衡量它”并且还需要确保你实际上在一个差异有用的区域工作 - 即如果选项 1 总是需要 10ns时间比选项2少,但是调用代码处理结果总是需要30秒,有关系吗?

标签: c# sql-server performance entity-framework database-performance


【解决方案1】:

您的查询正在编译并在您调用 ToDictionary 时执行,因此 1 和 2 应该相同并产生相同的查询:在这两种情况下您都会得到一个 SELECT FieldA, FieldB FROM table ORDER BY FieldA

第三个不同:您首先执行 SQL 查询(没有ORDER BY 子句),然后对内存中返回的集合进行排序(数据不是由 DB 提供程序排序,而是由客户端排序)。这可能会更快或更慢,具体取决于数据量、服务器和客户端的硬件、数据库的设计方式(索引等)、网络基础设施等。

根据您提供的信息无法判断哪个会更快

PS:这是没有意义的,因为 Dictionary 并不真正关心订单(我认为 3 不会编译,因为 Dictionary<>,如果我没记错的话,没有 OrderBy) ,但是将ToDictionary 更改为ToList,这就是你的性能答案

【讨论】:

  • 不,实际上,对于最常见的场景,1 和 2 会更快。通常,数据库提供程序(和服务器硬件)的排序速度通常比客户端的 CPU 快。但是真的没有办法说。两者都对较小的数据集进行排序...... SQL server 将在排序之前“投影”(如果你想这样称呼它)
  • 当然不会编译。字典有 keyvalue 道具而不是 FieldA :) 但可以订购...
  • @GiorgiNakeuri 是一个哈希集我认为排序根本不重要......但我没有真正尝试过:-)
  • @hbob 是的,3 应该慢一些,但实际上,没有办法说。它取决于除了 Linq-To-Entities 代码之外的许多因素
  • 不仅仅是数据的大小......如果您的 SQL 服务器的 CPU 和硬盘非常慢,并且数据集很大,但您的客户端有一个最新一代的 i7 和吨内存,排序字段没有索引,而是临时计算的?在这种情况下,客户端上的排序可能会更快。这是一个极端的情况,并不常见,但它是“可能的”。正如我所说,这取决于许多因素。但是如果你想要你的答案,除非你是肯定,否则会有这样的情况:使用 1 或 2... 而不是 3。
猜你喜欢
  • 2015-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-12
  • 2023-02-03
  • 2010-11-07
  • 2011-04-25
  • 1970-01-01
相关资源
最近更新 更多