【发布时间】: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