2015-04-14 4 views
3

У меня есть следующий запрос, который отлично работаетОптимизация запросов LINQ со счетом()

var myList = (from p in db.full 


         group p by p.object into g 
         orderby g.Count() descending 
         select new StringIntType 
         { 
          str = g.Key, 

          nbr = g.Count() 
         }).Take(50).ToList(); 

Проблема заключается в том, что это немного медленно из-за того, что я использую счетчик(), которое переводится на кол-(*).
мне нужно знать, если есть способ использовать счетчик (объект),

Вот что я получил в SQL Server Profiler

exec sp_executesql N'SELECT TOP (50) 
    [Project1].[C2] AS [C1], 
    [Project1].[object] AS [object], 
    [Project1].[C1] AS [C2] 
    FROM (SELECT 
     [GroupBy1].[A1] AS [C1], 
    [GroupBy1].[K1] AS [object], 
    1 AS [C2] 
    FROM (SELECT 
     [Extent1].[object], AS [K1], 
     COUNT(1) AS [A1] 
     FROM (SELECT 
[full].[mc_host_class] AS [mc_host_class], 
[full].[event_handle] AS [event_handle], 
[full].[mc_host_address] AS [mc_host_address], 
[full].[mc_object_class] AS [mc_object_class], 
[full].[mc_object] AS [mc_object], 
[full].[mc_incident_time] AS [mc_incident_time], 
[full].[date_reception] AS [date_reception], 
[full].[status] AS [status], 
[full].[mc_owner] AS [mc_owner], 
[full].[msg] AS [msg], 
[full].[duration] AS [duration], 
[full].[repeat_count] AS [repeat_count], 
[full].[mc_date_modification] AS [mc_date_modification], 
[full].[event_class] AS [event_class], 
[full].[bycn_ticket_remedy] AS [bycn_ticket_remedy], 
[full].[mc_host] AS [mc_host], 
[full].[acknowledge_by] AS [acknowledge_by], 
[full].[acknowledge_by_time] AS [acknowledge_by_time], 
[full].[assigned_by] AS [assigned_by], 
[full].[assigned_to] AS [assigned_to], 
[full].[assigned_by_time] AS [assigned_by_time], 
[full].[closed_b   y] AS [closed_by], 
[full].[closed_by_time] AS [closed_by_time], 
[full].[blacked_out] AS [blacked_out], 
[full].[bycn_liaison_type] AS [bycn_liaison_type], 
[full].[bycn_liaison_debit] AS [bycn_liaison_debit], 
[full].[cause] AS [cause], 
[full].[mc_location] AS [mc_location], 
[full].[mc_parameter] AS [mc_parameter] 
FROM [dbo].[full] AS [full]) AS [Extent1] 
     GROUP BY [Extent1].[object], 
     ) AS [GroupBy1] 
    ) AS [Project1] 
ORDER BY [Project1].[C1] DESC',N'@p__linq__0 datetime2(7),@p__linq__1 datetime2(7)',@p__linq__0='2015-03-14 00:00:00',@p__linq__1='2015-04-15 00:00:00' 
+0

В вашем случае я думаю, что SqlProfiler может помочь. Похоже, что сгенерированный запрос довольно прост, поэтому я не уверен, что есть возможность оптимизировать, например, добавлять индексы или другие трюки производительности в sql. –

+0

hmm, 'nbr = g.Select (a => 1) .Count()'? –

+0

@Jenea в sql-профилировщике подсчитывает все столбцы таблицы, которые занимают слишком много времени. –

ответ

2

Возможно, пара оптимизаций может сделать трюк:

  • Делает взятие первым, прежде чем выбрать
  • Count группы только один раз, используя ключевое слово LET

Так Metacode (этот код, написанный в блокноте и не компилируется!)

var topFifty = (
    from p in db.full 
    group p by p.object into g 
    let groupedCount = g.Count() 
    orderby groupedCount descending 
    select p.key, groupedCount 
    ) 
    .Take(50).ToList(); 

var topFifty.Select(x => new StringIntType 
    { 
     str = x.Key, 
     nbr = x.Count 
    }).ToList(); 
+0

Я отправляю, как выполняется перевод запроса в sql-профилировщике –

+1

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

+0

@drexdrex и как насчет выбора только ключа и счета? – oleksii

Смежные вопросы