performance - NHibernate LINQ 查询性能,哪个代码片段更好?

标签 performance linq fluent-nhibernate benchmarking queryover

这个问题是问以下两种方法中哪一种更受鼓励(以及原因是什么)?

我在使用 C# 4.0 的 ServiceStack REST 应用程序中使用 FluentNHibernate,但这个问题对 NHibernate LINQ 查询来说是普遍的。

是否更鼓励:

(方法 1) 快速运行一个简单 查询,返回与用户 ID 匹配的所有行:

// Query the User by id
var user = session.Get<User>(request.UserId);

然后分别在返回的List上使用LINQ来进一步缩小结果范围:

// 'User' contains a 'List<Location>'
var locations = user.Locations.Where(location =>
                        location.Timestamp >= (request.MinTimestamp.HasValue ? request.MinTimestamp.Value : 0) &&
                        location.Timestamp <= (request.MaxTimestamp.HasValue ? request.MaxTimestamp.Value : DateTime.Now.ToTimestamp()));

return locations;

(方法 2)或,更鼓励运行一个更复杂的查询,它在单个查询中执行上述操作:

var locationsQuery = session.QueryOver<LocationModel>()
                        .Where(table => table.User.Id == request.UserId)
                        .And(table => table.Timestamp >= (request.MinTimestamp.HasValue ? request.MinTimestamp.Value : 0))
                        .And(table => table.Timestamp <= (request.MaxTimestamp.HasValue ? request.MaxTimestamp.Value : DateTime.Now.ToTimestamp()));

return locationsQuery.List();

如果我的目标是:

a) 更快的执行时间


基准(修订版)

修订后的完整测试代码:http://pastebin.com/0ykKwcxX

基准输出:

方法 1 147.291 秒 5000 次迭代

上一次迭代的查询结果:
{ 时间戳=1348659703485,纬度=179.40000,经度=209.40000 }
{ 时间戳=1348659703486,纬度=179.55000,经度=209.55000 }
{ 时间戳=1348659703487,纬度=179.70000,经度=209.70000 }
{ 时间戳=1348659703488,纬度=179.85000,经度=209.85000 }
{ 时间戳=1348659703489,纬度=180.00000,经度=210.00000 }

方法 2 133.728 秒 5000 次迭代

上一次迭代的查询结果:
{ 时间戳=1348659703485,纬度=179.40000,经度=209.40000 }
{ 时间戳=1348659703486,纬度=179.55000,经度=209.55000 }
{ 时间戳=1348659703487,纬度=179.70000,经度=209.70000 }
{ 时间戳=1348659703488,纬度=179.85000,经度=209.85000 }
{ 时间戳=1348659703489,纬度=180.00000,经度=210.00000 }

差异:方法 2 大约快 13.5 秒。


b) 长期复用和稳定性

最佳答案

如果您的目标是更快的执行时间,那么我认为第二种方法最好,因为它不会对用户实体进行不必要的加载。话虽如此,我不是 NHibernate 用户所以不确定,并且可以肯定的是,如果它很重要,你应该进行一些测量性能测试(“你不能改进你无法测量的东西” - 不记得是谁说的,但这是一个很好的格言)。

Ayende 写了很多值得一看的优秀 NHibernate 帖子(例如 http://ayende.com/blog/3988/nhibernate-the-difference-between-get-load-and-querying-by-id)

当谈到“长期重用和稳定性”时,这取决于您如何使用此代码。您始终可以重构查询部分,以便您的 userid 和时间戳过滤器是扩展方法。有关示例,请参阅此帖子:http://lostechies.com/jimmybogard/2012/08/30/evolutionary-project-structure/

关于performance - NHibernate LINQ 查询性能,哪个代码片段更好?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12578019/

相关文章:

performance - 如果我们已经将分区键设置到 FeedOption 中,查询是否应该包含分区键?

java - Visualvm 中的自拍时间比其他时间长

c# - 什么使 LINQ 关联成为 EntitySet<table>?

c# - 如何以字母数字升序对这个字符串进行排序

c# - 相关表中的流利 nhibernate 鉴别器

javascript - 未捕获的类型错误 : Cannot read property 'children' of null

java - JSF 应用程序平均负载上升

C# Mongodb 将 List<BsonDocument> 合并为单个 BsonArray

c# - 使用 System.Data.OracleClient 配置 Fluent NHibernate

NHibernate 在单独的程序集中加入子类