2012-03-30 5 views
3

im folgenden Code habe ich auf die Zeile kommentiert, die meine Seite tief unten SLOWS. Ich habe einen Geschwindigkeitstest durchgeführt, um den CONTAINS LINQ Ausdruck zu enthüllen, ist das Problem.LINQ Performance-Problem auf nur ein paar hundert Datensätze

Weiß jemand, wie man diese eine Zeile ändert, um effizienter zu sein, indem man stattdessen etwas anderes verwendet. Ich bin auch neugierig, warum es so langsam ist.

Irgendwelche Ideen (Dank im Voraus):

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

Entschuldigung, aber Ihre Frage ist nicht nur ein Alptraum, sondern auch ein Alptraum. Niemand wird das in einem Jahr ohne viel Aufwand verstehen. –

+0

Überprüfen Sie den generierten SQL- und Abfrageplan. Dies ist der Weg, um Performance-Probleme in DB-Abfragen zu lösen – Nikolay

+0

Es ist nur diese eine Zeile, die langsam ist. results = (aus r in den Ergebnissen. Wo (x =>! HazardedBoolFiltered .Wählen Sie (y => y.Key.wastid) .Contains (x.WasteId)) wählen Sie r) .AsEnumerable(); – John

Antwort

0

Versuchen Any (MSDN)

Try this:

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

Oder Count:

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

Danke Ich habe eine Leistungsverbesserung mit Count – John

+0

.any() ist auch in Net 3.5 – HugoRune

+0

@HugoRune Edited thanks. Ich realisierte das seit, weiß nicht, warum ich dachte, dass es nicht war ?! Ich werde die Tatsache beschuldigen, dass ich diese Antwort an einem Freitag gegeben habe und ich schon im Wochenendmodus war :) hehe – mattytommo

1

Ich empfehle die Verwendung eines Logging/Tracing-Framework wie Smart inspect oder log4net in Kombination mit einem Debug-Text-Writer. http://www.codesprouts.com/post/View-LINQ-To-SQL-Statements-Using-A-Debug-TextWriter.aspx

eine andere Möglichkeit ist, den SQL Server Profiler zu verwenden und sehen, was sql linq2sql produziert.

auch eine sehr nette Möglichkeit ist, den MVC Mini Profiler in Kombination mit der Profiled DB Connection und dem SqlFormatters.SqlServerFormatter zu verwenden.

Verwandte Themen