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

Performance NHibernate LINQ查询性能,哪个代码片段更好?,performance,linq,fluent-nhibernate,benchmarking,queryover,Performance,Linq,Fluent Nhibernate,Benchmarking,Queryover,这个问题是问以下两种方法中哪一种更受鼓励,原因是什么 我正在使用C4.0在ServiceStack REST应用程序中使用FluentNHibernate,但这个问题对于NHibernate LINQ查询来说是通用的 是否更鼓励: 方法1快速运行一个简单查询,返回与用户id匹配的所有行: // Query the User by id var user = session.Get<User>(request.UserId); 然后分别使用返回列表上的LINQ进一步缩小结果范围: /

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

我正在使用C4.0在ServiceStack REST应用程序中使用FluentNHibernate,但这个问题对于NHibernate LINQ查询来说是通用的

是否更鼓励:

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

// Query the User by id
var user = session.Get<User>(request.UserId);
然后分别使用返回列表上的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();
如果我的目标是:

更快的执行时间

修订基准

修订的完整测试代码:

基准输出:

方法1在5000次迭代中花费了147.291秒

上次迭代的查询结果: {时间戳=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在5000次迭代中花费了133.728秒

上次迭代的查询结果: {时间戳=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帖子,值得一看


当谈到“长期重用和稳定性”时,这取决于您如何使用此代码。您可以随时重构查询部分,使您的userid和timestamp过滤器成为扩展方法。请参阅本文中的示例:

就执行时间而言,为什么不测试一下,看看呢?我很惊讶第二种方法似乎比较慢。您是否检查过NHibernate执行的SQL查询?您可以发布它们吗?在第一个场景中,您应该以两个查询结束,例如:select*from UserId=的用户,select*from UserId=的位置。在第二种情况下,我们应该只有一个查询:select*from Locations,其中UserId=。在您的测量中,第二个选项几乎慢了2倍-这让我感到惊讶。如果您将DateTime.Now.Timestamp移出查询并将其存储在temp变量中,会发生什么?是否在数据库中重复映射和执行此操作?正如@lowleveldesign所说,看到由NHibernate.var locationsQuery=.生成的原始SQL会很有趣。。。实际上根本没有查询数据库。变量是IQueryOver而不是List。这些测试甚至相等吗?