I have the following code that unfortunately is really slow:private void FilterSessionByDate(){  SessionsFilteredByDate =    BusinessClient.Instance.Tracker.GetAllMilestonesInSessionObjects().Where(                i => i.CreatedDate >= GetFromDate() && i.CreatedDate <= GetToDate());}private void FilterSessionsByTrackerId(){  SessionsFilteredByDateAndTrackerId =    SessionsFilteredByDate.Where(i=>i.TrackerId == CurrentItem.ID);}private void BindGrid(DateTime fromDate, DateTime toDate, int trackerId, int campaignId){  var result = BusinessClient.Instance.Tracker.GetReportForCampaign(trackerId, campaignId, fromDate, toDate);  foreach (var trackerReport in result)  {    trackerReport.Errors = GetErrors(trackerReport);  }  StatisticsGrid.DataSource = result.Where(r => r.ParentMilestoneId == null);  StatisticsGrid.DataBind();}private int GetErrors(TrackerReport milestone){  int counter = 0;  //var milestonesWithId = BusinessClient.Instance.Tracker.GetAllMilestonesInSessionWithTrackerId(CurrentItem.ID);  //var sessionsWithDateRange = milestonesWithId.Where(i=> i.CreatedDate >= GetFromDate() && i.CreatedDate <= GetToDate());  var sessionsWithStatusError = SessionsFilteredByDateAndTrackerId.Where(i => i.StatusId == 0);  foreach (var milestonesInSession in sessionsWithStatusError)  {    // Get all milestoneinsessions with this session    MilestonesInSession session = milestonesInSession;    var localPath = BusinessClient.Instance.Tracker.GetAllMilestonesInSessionObjects().Where(                    i => i.SessionId == session.SessionId).ToList();    var lastStep = localPath.Max(i => i.MilestoneId);    var latestTime = localPath.Where(i => i.MilestoneId != lastStep).Max(i=>i.CreatedDate);    var milestoneWithLatestTime = localPath.First(x => x.CreatedDate == latestTime);    if (milestonesInSession.MilestoneId != milestone.MilestoneId)    {      if (milestoneWithLatestTime.MilestoneId == milestone.MilestoneId &&          milestoneWithLatestTime.CreatedDate.AddSeconds(2) >= milestonesInSession.CreatedDate)        counter++;    }    else     {      // It is the last milestone, we have to check if the milestone with      // the latest time is close to this one, otherwise the error happened      // at the last step      if (milestonesInSession.CreatedDate > milestoneWithLatestTime.CreatedDate.AddSeconds(2))        counter++;    }  }  return counter;}The MilestonesInSessions in the database are 2 millions, but I managed to optimize the queries, so that the retrieving of them are pretty fast. Anyway, having multiple nested foreach affects its speed, given that:The result variable is always with 10 entries.  The sessionStatusWithError variable has generally around 100 entries.  The localpath variable is always with 10 entries.IQueryable[RequiresDataAccessSynchronized]public IQueryable<MilestonesInSession> GetAllMilestonesInSessionObjects(){  var query = from m in _milestonesInSessionRepository.GetAll()              select m;  return query;}MilestonesInSessionpublic class MilestonesInSession : DataAccessBase2, IDataOperations<Model.Tracker.MilestonesInSession, Model.Tracker.MilestonesInSession>{  #region IDataOperations<MilestonesInSession,int> Members  public IQueryable<Model.Tracker.MilestonesInSession> GetAll()  {    var query = from milestoneSession in     _dataContext.Repository<Linq.TrackerMilestonesInSession>()    select new Model.Tracker.MilestonesInSession    {      MilestoneId = milestoneSession.MilestoneId,      CreatedDate = milestoneSession.CreatedDate,      SessionId = milestoneSession.SessionId,      ProductId = milestoneSession.ProductId,      TrackerId = milestoneSession.TrackerId,      StatusId = milestoneSession.StatusId,      BankId = milestoneSession.BankId    };    return query;  }Ants Performance profiler screenshots:Do you know how can I optimize it to get a instant/better result instead of waiting at least 10 seconds every time?
Getting instant/better result instead of waiting at least 10 seconds every time
c#;performance;sql;linq;asp.net