2011-06-06 97 views
14

我有一个简单的测试,运行查询5000次。查询的LINQ版本接管3倍HQL和缓存LINQ的版本比HQLNHibernate的Linq查询比HQL慢3倍

HQL的缓存版本显著慢:

session.CreateQuery(String.Format("from Episode where SeriesId='{0}' and SeasonNumber='{1}' and EpisodeNumber='{2}'", seriesId, seasonNumber, episodeNumber)) 
       .SetMaxResults(1) 
       .SetCacheable(true) 
       .UniqueResult<Episode>(); 

的Linq:

session.Query<Episode>() 
     .Where(c => c.SeriesId == seriesId && c.SeasonNumber == seasonNumber && c.EpisodeNumber == episodeNumber) 
     .Cacheable() 
     .FirstOrDefault(); 

以下是结果

 
HQL: Cached: less than a second No-Cache: 5 seconds 
LINQ: Cached: 8 seconds   No-Cache: 15 seconds 

我只是想确保我正在经历预期的开销,而不是我做错的事情。

如果那个头脑在那里,而且我没有太多的事情可以做,那么你是否可以提出一个中间立场,那将需要更少的字符串,但提供更好的性能?

注: 在功能NHibernate .Cache(c => c.UseQueryCache().UseSecondLevelCache().UseMinimalPuts().ProviderClass<HashtableCacheProvider>())

+0

对于所有5000次迭代,linq test生成的sql语句“完全”相同吗? – Rippo 2011-06-07 16:53:24

+0

我不认为它的SQL语句,因为甚至没有命中数据库的缓存版本是8秒,而不是1。在这两种情况下,数据库只被命中一次。 – 2011-06-07 16:56:00

+0

对不起,应该是我的观点,你确定数据库只有一次命中linq版本? – Rippo 2011-06-07 17:18:10

回答

10

我的缓存设置我想这个问题如下。这个查询:

session.Query<Episode>() 
     .Where(c => c.SeriesId == seriesId && c.SeasonNumber == seasonNumber && c.EpisodeNumber == episodeNumber) 
     .Cacheable() 
     .FirstOrDefault(); 

加载所有从数据库中的情节,将它们放入缓存,然后返回集合的第一个实例。当调用FirstOrDefault时,将执行对Where(c => c.SeriesId == seriesId && c.SeasonNumber == seasonNumber && c.EpisodeNumber == episodeNumber)的查询,然后将FirstOrDefault应用于返回的整个序列。

喜欢的东西:执行

  1. .Where(c => c.SeriesId == seriesId && c.SeasonN... SQL如果你尝试类似

    session.Query<Episode>() 
         .Where(c => c.SeriesId == seriesId && c.SeasonNumber == seasonNumber && c.EpisodeNumber == episodeNumber) 
         .Cacheable() 
         .SetMaxResults(1) 
         .UniqueResult(); 
    

  2. .FirstOrDefault()评估超过1

所以集合中的所有元素它应该像你的HQL查询一样行事年。