2014-04-29 166 views
1

我已經寫在LINQ到實體查詢:查詢執行時間與在SQL Server

db.Table<Operation>() 
    .Where(x => x.Date >= dateStart) 
    .Where(x => x.Date < dateEnd) 
    .GroupBy(x => new 
    { 
     x.EntityId, 
     x.EntityName, 
     x.EntityToken 
    }) 
    .Select(x => new EntityBrief 
    { 
     EntityId = x.Key.EntityId, 
     EntityName = x.Key.EntityName, 
     EntityToken = x.Key.EntityToken, 
     Quantity = x.Count() 
    }) 
    .OrderByDescending(x => x.Quantity) 
    .Take(5) 
    .ToList(); 

的問題是,它使用EF在應用程序執行時需要4秒。但是,當我從該查詢對象(使用Log)中創建純SQL查詢並直接在SQL Server上激發它時,則需要0秒。這是一個已知的問題嗎?

+0

您是否嘗試過使用探查器將其縮小?如果沒有'Take(5)',我會懷疑創建對象,但是5個對象應該很快...... – ChrFin

+0

您能推薦這樣一個分析器嗎? – cryss

+0

我們在這裏使用dotTrace。 – ChrFin

回答

0

的問題是與數據庫鎖。我使用了錯誤的隔離級別,所以在某些情況下我的查詢被阻止。現在我使用read-commited-snapshot並且執行時間看起來不錯。

0

首先,請嘗試提高查詢:

var entityBriefs = 
    Table<Operation>().Where(x => x.Date >= dateStart && x.Date < dateEnd) 
        .GroupBy(x => x.EntityId) 
        .OrderByDescending(x => x.Count()) 
        .Take(5) 
        .Select(x => new EntityBrief 
        { 
         EntityId = x.Key.EntityId, 
         Quantity = x.Count() 
        }); 

var c = entityBriefs.ToDictionary(e => e.EntityId, e => e); 

var entityInfo = Table<Operation>().Where(o => mapping.Keys.Contains(o.EntityId).ToList(); 

foreach(var entity in entityInfo) 
{ 
    mapping[entity.EntityId].EntityName = entity.EntityName; 
    mapping[entity.EntityId].EntityToken = entity.EntityToken; 
} 

您也可以與CompiledQuery.Compile幫助編譯查詢,並與改進的性能進一步使用它。

http://msdn.microsoft.com/en-us/library/bb399335%28v=vs.110%29.aspx

+0

我不認爲有兩次'x.Count()'是一種改進。 –

+0

秒計數僅在5組內計算。在其他情況下,您必須將整個數據集投影到EntityBrief – Andrew

+0

編譯不是不必要的,因爲如果我選擇較短的術語,那麼執行時間非常短。所以這個問題(執行時間的差異)只有在處理大量數據時才存在。 – cryss