3

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

我正在使用 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

基准输出:

方法 15000 次迭代中花费了147.291 秒

查询最后迭代的结果:
{时间戳= 1348659703485,纬度= 209.40000}
{时间戳= 1748659703486,Latitude = 179.55000,Vongitude = 209.55000}
{时间戳= 1348659703487,Latitude = 179.70000,Vongitude = 209.70000}
{时间戳= 1348659703488 , 纬度=179.85000, 经度=209.85000 }
{ 时间戳=1348659703489, 纬度=180.00000, 经度=210.00000 }

方法 25000 次迭代中花费了133.728 秒

查询最后迭代的结果:
{时间戳= 1348659703485,纬度= 209.40000}
{时间戳= 1748659703486,Latitude = 179.55000,Vongitude = 209.55000}
{时间戳= 1348659703487,Latitude = 179.70000,Vongitude = 209.70000}
{时间戳= 1348659703488 , 纬度=179.85000, 经度=209.85000 }
{ 时间戳=1348659703489, 纬度=180.00000, 经度=210.00000 }

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


b) 长期重复使用和稳定性

4

1 回答 1

1

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

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

When it comes to 'long term re-use and stability' this kind of depends how you're using this code. You could always refactor the query part so that your userid and timestamp filters are extension methods. See this post for an example: http://lostechies.com/jimmybogard/2012/08/30/evolutionary-project-structure/

于 2012-09-25T07:54:57.103 回答