2010-04-29 21 views
3

我有一個linq查詢導致一些超時問題。基本上,我有一個查詢返回一個包含大約500,000條記錄的表的前100個結果。Linq。幫我調整一下!

下面是該查詢:

using (var dc = CreateContext()) 
     { 
      var accounts = string.IsNullOrEmpty(searchText) 
          ? dc.Genealogy_Accounts 
           .Where(a => a.Genealogy_AccountClass.Searchable) 
           .OrderByDescending(a => a.ID) 
           .Take(100) 
          : dc.Genealogy_Accounts 
           .Where(a => (a.Code.StartsWith(searchText) 
              || a.Name.StartsWith(searchText)) 
              && a.Genealogy_AccountClass.Searchable) 
           .OrderBy(a => a.Code) 
           .Take(100); 
      return accounts.Select(a => 
     } 
    } 

奇怪的是它是導致超時第一個LINQ查詢。我認爲通過做'Take'我們不需要掃描所有500k條記錄。但是,這一定是正在發生的事情。我在猜測,發現什麼是「可搜索」的連接正在引發這個問題。我無法對錶格進行非規範化......所以我想知道是否有一種方法來重寫linq查詢以使其更快地返回......或者如果我只需將此查詢寫爲存儲過程(和如果是這樣,它可能看起來像什麼)。謝謝。

+0

哪些列在每個表中編入索引? – 2010-04-29 20:47:51

回答

14

那麼首先,我會找出正在生成什麼查詢(在LINQ to SQL中,您將設置數據上下文的日誌),然後在SQL Server Management Studio中對其進行配置。在那裏玩,直到你找到足夠快的東西(通過改變查詢或添加索引),並且如果你不得不改變查詢,找出如何在LINQ中表示。

我懷疑問題是,你結合OrderByTake - 這意味着它可能需要找出所有結果,以便制定出前100看起來這等。 Code索引?如果沒有,嘗試索引 - 它可以幫助通過允許服務器按照它們返回的順序來考慮記錄,所以它可以在找到100條記錄後停止。您也應該查看其他列的索引。

+1

+5(哦,等待......)在可能未索引的字段上進行orderby/take組合。 Linq to SQL只和支持它的數據庫一樣好。 – GalacticCowboy 2010-04-29 20:47:24

+0

因此,最後通過對數據庫進行一些調整,我能夠提高性能。我會繼續做更多,但現在是可以接受的。代碼和名稱已編入索引,但「AccountClass」的FK不是。爲此添加索引有助於正在發生的連接。感謝所有迴應的人! – dtrick 2010-04-30 17:59:07

3

Take(100)轉換爲「Select Top 100」等。如果您的問題是一個非常龐大的結果集,其中有很多列返回,這將有所幫助。我敢打賭,你的問題是查詢產生的表掃描。在這種情況下,.Take(100)可能根本沒有幫助。

所以,可能的罪魁禍首是相同的,如果你使用ADO.NET做SQL:你的Indxes是怎樣的?這些字段是您沒有良好索引的搜索字段嗎?與確實利用良好指標的查詢相比,這會導致性能的急劇下降。添加包含CodeName的索引並查看會發生什麼。由於Order By,因此Code不使用索引保證可以吸引你。此外,什麼字段鏈接家譜_帳戶 Genealogy_AccountClass?在任何一張桌子上都缺乏索引可能會導致事情發生(我猜包括檢索是不太可能有幫助的指數。)

使用SQL Profiler看到實際的查詢正在運行(雖然你可以做到這一點在VS太),並看到它確實是在多麼糟糕服務器。

問題可能是是LINQ做一些愚蠢的生成查詢,但這可能並非如此。我們發現LINQ-to-SQL經常比我們做更好的查詢。 Even if it looks goofy, it's usually very efficient。您可以將SQL放入查詢分析器中,並查看查詢計劃。然後重寫SQL更簡單一些,看看它是否改善了事情 - 我敢打賭它不會。我認爲你仍然會看到表掃描,表明你的索引有問題。