7

ОСНОВНОЙ ВОПРОС Есть ли какое-то известное ограничение, snafu, проблема с конфигурацией, что могло бы объяснить тот факт, что все вещи равны, запрос, выполняемый с C# linq, может принимать заказ дольше, чем при любом другом режиме?LINQ Query очень медленный по сравнению с SSMS

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

var query = (
    from content in context.ApprovedContentView 
       where content.BucketId == 13098 && content.ContentTypeId == 5220 
    join item in context.ActiveContent 
       on content.ContentId equals item.ItemId 
     where 
       item.IsSuchAndSuch == true && item.SomeOtherProperty == 5000 
     select new 
     { 
      ItemId = item.ItemId, 
      Title = item.Title, 
      SubTitle = item.SubTitle, 
      DescriptionText = item.DescriptionText, 
      /* about 10 other scalar fields */ 

     }); 

int count = query.Count(); 
var data = query.OrderByDescending(item => item.ItemId).Skip(5).Take(3); 

А вот (сокращенно/formmatted) SQL он генерирует

SELECT 
[GroupBy1].[A1] AS [C1] 
FROM (SELECT 
    COUNT(1) AS [A1] 
    FROM  [SchemaX].[ApprovedContentView] AS [Extent1] 
    INNER JOIN [SchemaX].[ActiveContent] AS [Extent2] ON [Extent1].[ContentId] = [Extent2].[ItemId] 
    WHERE (13098 = [Extent1].[BucketId]) AND (5220 = [Extent1].[ContentTypeId ]) AND 
    (1 = [Extent2].[IsSuchAndSuch]) AND (5000 = [Extent2].[SomeOtherProperty ]) 
) AS [GroupBy1] 
GO 

SELECT TOP (3) 
[Filter1].[BucketId] AS [BucketId], 
[Filter1].[ItemId] AS [ItemId], 
[Filter1].[Title] AS [Title], 
[Filter1].[SubTitle] AS [SubTitle], 
[Filter1].[DescriptionText] AS [DescriptionText], 
/* other fields */ 
FROM (SELECT 
      [Extent1].[BucketId] AS [BucketId], 
      [Extent2].[ItemId] AS [ItemId], 
      [Extent2].[Title] AS [Title], 
      [Extent2].[SubTitle] AS [SubTitle], 
      [Extent2].[DescriptionText] AS [DescriptionText], 
      /* other fields */ 
      row_number() OVER (ORDER BY [Extent2].[DealId] DESC) AS [row_number] 
    FROM [SchemaX].[ApprovedContentView] AS [Extent1] 
    INNER JOIN [SchemaX].[ActiveContent] AS [Extent2] ON [Extent1].[ContentId] = [Extent2].[ItemId] 
    WHERE (13098 = [Extent1].[BucketId]) AND (5220 = [Extent1].[ContentTypeId ]) AND 
      (1 = [Extent2].[IsSuchAndSuch]) AND (5000 = [Extent2].[SomeOtherProperty ]) 
) AS [Filter1] 
WHERE [Filter1].[row_number] > 5 
ORDER BY [Filter1].[DealId] DESC 

РАЗЛИЧНЫЕ СЦЕНАРИИ я основываясь мои тесты скорости на соблюдение запросов, выполняемых с помощью SQL Profiler

В МЕСТЕ , когда этот запрос linq выполняется как часть его нормальной работы в моем приложении C#, я замечаю, что в sql-профайлере счетчик выбора занимает полные 3 секунды до c omplete и странно, запрос, который производит проекцию, занимает всего 200 мс, а времена повторяемы, что, по-видимому, исключает проблему кэша плана выполнения запроса. (работает с каркасом объекта 5, SQL Server 2008 R2)

В LINQPad , когда я исполняю заявление Linq через LINQPad, используя контекст данных DLL в # приложении C в ШЕРСТИ, количество и проекции каждого полным в соответствии с четвертью второй (~ 224 мс, для общего времени работы ~ 450 мс).

В SSMS независимо от источника SQL, когда я скопировать фактический код, который SQL Profile сообщает, что он Execute и вставить его в студии окна управления и выполнения, она занимает около 224ms.

настройка базы данных В SSMS, когда я оценить фактическое выполнение плана для SQL, что я скопировать из профайлера (либо из кода или LINQPad), я считаю, что SQL использует все правильные индексы, и отчетности только индекс ищет - нет сканирует таблицы, нет поиска для поиска.

Итак, что дает? Кто-нибудь видел что-нибудь подобное?

+0

Возможно, у вас есть кэшированный план выполнения, который устарел? Можете объяснить, почему вы видите это только тогда, когда вы ударяете его из своего приложения. – FlyingStreudel

+0

Сколько строк оно возвращает? Это первый запрос вашего приложения? – ken2k

ответ

5

Я бы удостоверился, что у вас нет плохого плана выполнения, который был кэширован для вашего приложения. Это часто случается со мной при работе с схемой работы с базой данных, которая уже используется. Возможно, у вас есть план выполнения, который был кэширован для контекста выполнения приложений, который неэффективен из-за изменений схемы, в то время как план выполнения, созданный для ваших запросов SSMS, является актуальным и не видит этих проблем с производительностью.

Я бы попытался использовать DBCC FREEPROCCACHE, чтобы принудительно обновить ваши планы выполнения и посмотреть, устраняет ли это проблему.

+0

это, кажется, сломало лог-джем. Спасибо!! – groggyjava

+0

Это сработало для меня. Точный запрос, выполняемый против моей локальной базы данных, длился 44 секунды в EF, последовательно. Я захватил запрос в профилировщике и запустил его в SSMS, и он завершался менее чем за 1 секунду. Я переключался между ними, запуская одинаковый запрос в обоих случаях, и эти огромные различия во времени были согласованными. Сразу после запуска DBCC FREEPROCCACHE оба запроса выполнялись менее чем за 1 секунду. – Triynko

0

ARITHABORT по умолчанию включен в SSMS и OFF по умолчанию для соединения SqlClient.

Если проблема появляется снова добавить:

new SqlCommand("SET ARITHABORT ON", connection).ExecuteNonQuery(); 
Смежные вопросы