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查詢一樣行事年。