2016-06-02 1 views
0

У меня есть список команд из 15 000 человек, которым нужен отдельный запрос linq для возврата результатов.Несколько запросов LINQ to SQL. Оптимизация перечисления

А именно - [Выберите последние 10 игр для «команды»]

public IEnumerable<ResultsByDate> SelectLast10Games(DateTime date, string team) 
     { 
      return 
      ( from e in db.E0s 
       where e.DateFormatted < date && 
       (e.HomeTeam == team || e.AwayTeam == team) 
       orderby e.Date descending 
       select new ResultsByDate 
       { 
        Date = e.Date, 
        HomeTeam = e.HomeTeam, 
        AwayTeam = e.AwayTeam, 
        HomeGoals = e.FTHG, 
        AwayGoals = e.FTAG 
       } 
      ).Take(10); 
     } 

Этот запрос, вероятно, хорошо, кажется, достаточно быстро, когда называется 15000 раз.

Моя настоящая проблема заключается в том, что я должен перечислять каждый запрос, и это действительно убивает производительность.

Для каждого из этих запросов мне нужно запустить метод по 10 результатам и, следовательно, запросы нужно перечислить.

Вопрос в том, как я могу избежать 15 000 перечислений?

Я думал о размещении каждого из результатов в большой список и затем вызова .ToList() или что-то лучшее, но добавление в список перебирает, как она идет вдоль так что это не кажется жизнеспособным.

Есть ли способ объединить все 15000 LINQ запросы в один гигантский запрос LINQ, такие как ..

public IEnumerable<ResultsByDate> SelectLast10Games(DateTime date, List<string> Teams) 
     { 
      foreach(var team in Teams) 
      { var query = 
        (from e in db.E0s 
        where e.DateFormatted < date && 
        (e.HomeTeam == team || e.AwayTeam == team) 
        orderby e.Date descending 
        select new ResultsByDate 
        { 
        Date = e.Date, 
        HomeTeam = e.HomeTeam, 
        AwayTeam = e.AwayTeam, 
        HomeGoals = e.FTHG, 
        AwayGoals = e.FTAG 
        } 
        ).Take(10); 
      } 
     } 

Так заносить бы один огромный результирующий набор, который я могу затем перечислить на одном дыхании и работе оттуда ?

Я пробовал, но я не могу получить правильную петлю LINQ (если это возможно - и лучший способ исправить мою проблему).

Вся программа занимает ~ 29 минут. Без перечисления около 30 секунд, что не удивительно, но удовлетворительно, учитывая критерии.

Спасибо!

ответ

1

Это можно выполнить с помощью Teams.Select(team => ..)

var query = Teams 
       .Select(team => 
        db.E0s 
        .Where(e => e.DateFormatted < date && (e.HomeTeam == team || e.AwayTeam == team)) 
        .OrderByDescending(e => e.Date) 
        .Select(
         e => 
         new ResultsByDate { 
          Date = e.Date, 
          HomeTeam = e.HomeTeam, 
          AwayTeam = e.AwayTeam, 
          HomeGoals = e.FTHG, 
          AwayGoals = e.FTAG 
         } 
        ) 
        .Take(10) 
      ) 

Если вы ищете лучшее исполнение для сильно запросов, вы должны рассмотреть возможность использования SQL хранимой процедуры и вызова его с помощью ADO.NET, Dapper или EntityFramework (Порядок выбора - от оптимального до тривиального) Моя рекомендация используется Dapper. Это ускорит ваш запрос, особенно если таблица проиндексирована правильно.

0

Кормить 15k параметры эффективно в сервер, Вы можете использовать TVP: http://blog.mikecouturier.com/2010/01/sql-2008-tvp-table-valued-parameters.html

Моя реальная проблема в том, что я должен перечислить каждый запрос, и это действительно убивает производительность.

Если вы не перечислите результат, на сервере нет никакого вызова. Поэтому неудивительно, что это быстро, без перечисления. Но это не означает, что перечисление является проблемой.