2

我對Sql Server查詢執行時間有很大的問題,我已經調試了很長時間沒有成功。LINQ to entities slow查詢

基本上我生成一個報告,其中「訂單」統計按訂單分組並顯示給用戶。問題是,大多數情況下查詢執行速度相當快,但偶爾它會直線下降,並導致服務器超時。

我從中得到的結果是,偶爾性能差的查詢性能似乎是由SQL Server中的參數嗅探引起的。我的關係有很多相關的行;某個關係對於一個父行可能有10000行,但下一行可能只有1個相關行。我認爲這會導致查詢優化器在某些情況下完全忽略索引並導致非常糟糕的性能。

基本上我不知道如何解決這個問題的方法。我不得不以某種方式優化我的查詢,或者想出一些方法來強制查詢優化器每次都使用索引。不幸的是,存儲過程不是這個項目的一個選項。

我試過的是爲每個'訂單'創建獨立的請求,但作爲系統中的1000多個訂單,導致大量緩慢,並且不是一個選項。我已經得到它在合理的執行時間內運行的最接近的是下面的查詢,它反過來似乎受到參數嗅探問題的影響。

result = (from ord in db.Orders 
    join comm in db.Comments.Where(i => 
    i.UserId == userId && 
    i.Created >= startDate && 
    i.Created < endDate && 
    i.UserGroupId == channelId && 
    i.Campaign.CampaignCountryId == countryId && 
    (i.CommentStatus.Name == CommentStatus.Approved || i.CommentStatus.Name == CommentStatus.Pending)) 
    on ord.OrderId equals comm.OrderId into Comments 

    join motif in db.Motifs.Where(i => 
    i.UserId == userId && 
    i.Created > startDate && 
    i.Created < endDate && 
    i.UserGroupId == channelId && i.Campaign.CampaignCountryId == countryId) 
    on ord.OrderId equals motif.OrderId into Motifs 

    where ord.EndDate > startDate 

    select new ReportRow() 
    { 
     OrderName = ord.Name, 
     OrderId = ord.OrderId, 
     ChannelId = channelId, 

     Comments = Comments.Count(c => c.CommentStatus.Name == CommentStatus.Approved), 
     PendingComments = Comments.Count(c => c.CommentStatu.Name == CommentStatus.Pending), 

     Motifs = Motifs.Count(), 
     UniqueMotifs = Motifs.GroupBy(c => c.Uin).Count(), 

     ApprovedValue = ((decimal?)Motifs.GroupBy(c => c.Uin).Select(c => c.FirstOrDefault()).Sum(c => c.Value) ?? 0) + ((decimal?)Comments.Where(c => c.Commentstatu.Name == Commentstatus.Approved).Sum(c => c.Value) ?? 0), 

     PendingValue = ((decimal?)Comments.Where(c => c.Commentstatu.Name == Commentstatus.Pending).Sum(c => c.Value) ?? 0) 
    }).ToList(); 

return result; 

任何幫助,以及如何使我的報告經營理念相當快的,每次將不勝感激 - 不管它的查詢優化自身或某些真棒想法,一般在SQL報告。

我正在使用Azure SQL,如果這有什麼區別。

另請注意,當我運行SSMS中上述LINQ生成的查詢時,我在每次運行時都會獲得很好的查詢執行時間,所以數據庫設計在這裏不應該成爲問題,儘管它可能不是最有效的無論如何。

+0

也許不是你的答案,只是一個想法。您可以爲報告創建一個視圖,然後查詢視圖以獲取結果。這將確保查詢在每次從SQL中運行正常,從你說的。 – 2014-12-13 12:23:58

+0

嘿,謝謝你的評論!還沒有真正嘗試創建視圖。你能指點我一個正確的方向來開始他們嗎? – veturi 2014-12-13 12:37:31

+0

我已經發布了一個答案,你可以在那裏查詢細節。 – 2014-12-13 12:40:00

回答

0

也許不是你的答案,只是一個想法。您可以爲報告創建一個視圖,然後查詢視圖以獲取結果。這將確保查詢在每次從SQL中運行正常,從你說的。

您使用它們類似於表格,並且可以對它們進行任何查詢。

查看帖子在some tips on consuming views in EF

+0

謝謝你的回答。不幸的是,視圖並不能解決我的問題,因爲我需要根據一些變量來執行查詢 - 您可以在我的原始SQL LINQ代碼中看到它們。正如存儲過程一樣,視圖在這個項目中也是不可接受的解決方案。 – veturi 2014-12-14 09:38:34