2012-03-30 64 views
3

在下面的代碼中,我已經評論了將我的頁面放慢的行。我做了一些速度測試來揭示LINQ表達式是否是CONTAINS的問題。只有幾百條記錄的LINQ性能問題

是否有人知道如何改變這一行,以更有效地使用其他的東西。我也很好奇它爲什麼如此緩慢。

任何想法(在此先感謝):

var allWaste = _securityRepository.FindAllWaste(userId, SystemType.W); 
    var allWasteIndicatorItems = _securityRepository.FindAllWasteIndicatorItems(); 

    // First get all WASTE RECORDS 
    var searchResults = (from s in allWaste 
         join x in allWasteIndicatorItems on s.WasteId equals x.WasteId 
         where (s.Description.Contains(searchText) 
         && s.Site.SiteDescription.EndsWith(searchTextSite) 
         && (s.CollectedDate >= startDate && s.CollectedDate <= endDate)) 
         && x.EWC.EndsWith(searchTextEWC) 
         select s).Distinct(); 

    var results = searchResults.AsEnumerable(); 

    if (hazardous != "-1") 
    { 
     // User has requested to filter on Hazardous or Non Hazardous only rather than Show All 
     var HazardousBoolFiltered = (from we in _db.WasteIndicatorItems 
     .Join(_db.WasteIndicators, wii => wii.WasteIndicatorId, wi => wi.WasteIndicatorId, (wii, wi) => new { wasteid = wii.WasteId, wasteindicatorid = wii.WasteIndicatorId, hazardtypeid = wi.HazardTypeId }) 
     .Join(_db.HazardTypes, w => w.hazardtypeid, h => h.HazardTypeId, (w, h) => new { wasteid = w.wasteid, hazardous = h.Hazardous }) 
     .GroupBy(g => new { g.wasteid, g.hazardous }) 
     .Where(g => g.Key.hazardous == true && g.Count() >= 1) 
            select we).AsEnumerable(); // THIS IS FAST 

     // Now join the 2 object to eliminate all the keys that do not apply 
     if (bHazardous) 
      results = (from r in results join x in HazardousBoolFiltered on r.WasteId equals x.Key.wasteid select r).AsEnumerable(); //This is FAST 
     else 
      results = (from r in results.Where(x => !HazardousBoolFiltered 
       .Select(y => y.Key.wasteid).Contains(x.WasteId)) select r).AsEnumerable(); // This is DOG SLOW 10-15 seconds !--- THIS IS SLOWING EXECUTION by 10 times --! 


    } 


    return results.AsQueryable(); 
+4

很抱歉地說,但您的查詢不僅是一場表演噩夢,也是一場維護噩夢。沒有人會在一年內毫不費力地理解這一點。 – 2012-03-30 09:18:07

+0

檢查生成的sql和查詢計劃。這是解決db查詢中性能問題的方法 – Nikolay 2012-03-30 09:19:09

+0

它只是這一行很慢。 (x =>!HazardousBoolFiltered .Select(y => y.Key.wasteid).Contains(x.WasteId))select r).AsEnumerable();結果=(from r in results.Where(x =>! – John 2012-03-30 09:38:56

回答

0

嘗試AnyMSDN

試試這個:

results = (from r in results 
    .Where(x => !HazardousBoolFiltered 
     .Any(y => y.Key.wasteid == r.WasteId))) 
    .AsEnumerable() 

或者Count

results = (from r in results 
    .Where(x => HazardousBoolFiltered 
     .Count(y => y.Key.wasteid == r.WasteId) == 0)) 
    .AsEnumerable() 
+0

謝謝我得到了性能改善使用計數 – John 2012-03-30 14:30:14

+0

.any()也在網絡3.5 – HugoRune 2012-04-27 20:16:34

+0

@HugoRune編輯謝謝。我意識到那以後,不知道爲什麼我認爲它不是?!我會責怪我在星期五給出了這個答案,而我已經在週末模式:)嘿 – mattytommo 2012-04-27 20:18:44