Запрос выполняется менее чем за миллисекунду в SQL, но время в Entity Framework

Следующий запрос linq-to-entities бросает

Время ожидания для платформы Entity Framework истекло. Период ожидания, прошедший до завершение операции или сервер не отвечает.

после ToList().

 var q = (from contact 
          in cDB.Contacts.Where(x => x.Templategroepen.Any(z => z.Autonummer == templategroep.Autonummer) 
                                && !x.Uitschrijvings.Any(t => t.Templategroep.Autonummer == templategroep.Autonummer)) 
          select contact.Taal).Distinct();

((System.Data.Objects.ObjectQuery)q).ToTraceString() дает мне:

SELECT 
[Distinct1].[Taal] AS [Taal]
FROM ( SELECT DISTINCT 
[Extent1].[Taal] AS [Taal]
FROM [dbo].[ContactSet] AS [Extent1]
WHERE ( EXISTS (SELECT 
1 AS [C1]
FROM [dbo].[TemplategroepContact] AS [Extent2]
WHERE ([Extent1].[Autonummer] = [Extent2].[Contacts_Autonummer]) AND ([Extent2].[Templategroepen_Autonummer] = @p__linq__0)
)) AND ( NOT EXISTS (SELECT 
1 AS [C1]
FROM [dbo].[UitschrijvingenSet] AS [Extent3]
WHERE ([Extent1].[Autonummer] = [Extent3].[Contact_Autonummer]) AND ([Extent3].[Templategroep_Autonummer] = @p__linq__1)
))
)  AS [Distinct1]

запрос от трассировки работает менее чем за 1 секунду в студии управления sql, но время, когда на самом деле перечисляет его? как это возможно снова?

* Обновление: добавлен вывод SQL PROFILER для запроса *, это работает медленнее, чем EF ToList() ( > 30 секунд)

exec sp_executesql N'SELECT 
[Distinct1].[Taal] AS [Taal]
FROM ( SELECT DISTINCT 
    [Extent1].[Taal] AS [Taal]
    FROM [dbo].[ContactSet] AS [Extent1]
    WHERE ( EXISTS (SELECT 
        1 AS [C1]
        FROM [dbo].[TemplategroepContact] AS [Extent2]
        WHERE ([Extent1].[Autonummer] = [Extent2].[Contacts_Autonummer]) AND ([Extent2].[Templategroepen_Autonummer] = @p__linq__0)
    )) AND ( NOT EXISTS (SELECT 
        1 AS [C1]
        FROM [dbo].[UitschrijvingenSet] AS [Extent3]
        WHERE ([Extent1].[Autonummer] = [Extent3].[Contact_Autonummer]) AND ([Extent3].[Templategroep_Autonummer] = @p__linq__1)
    ))
)  AS [Distinct1]',N'@p__linq__0 int,@p__linq__1 int',@p__linq__0=1,@p__linq__1=1

Ответ 1

Я наблюдал эту проблему с EF6.

await _context.Database.SqlQuery<MyType>(sql) был отключен, даже когда мое значение тайм-аута зависало до 60 секунд. Тем не менее, выполнение одного и того же SQL (используемый профилировщик для подтверждения того, что sql, который я прошел, не был изменен) в SSMS дал ожидаемые результаты за одну секунду.

exec sp_updatestats

Исправлена ​​проблема для меня.

Ответ 2

Я знаю, что это немного поздно, но я нашел ответ здесь.

В основном Entity Framework любит отслеживать все по умолчанию. Если вам это не нужно (т.е. Не вставлять, не обновлять или удалять объекты), выключите его, чтобы ускорить выполнение запросов.

Если вы используете Entity Framework Code First, вы можете добиться этого так:

var q = (from contact
      in cDB.Contacts.AsNoTracking()
          .Where(x => x.Templategroepen.Any(z => z.Autonummer == templategroep.Autonummer) 
                            && !x.Uitschrijvings.Any(t => t.Templategroep.Autonummer == templategroep.Autonummer)) 
      select contact.Taal).Distinct();

Ответ 3

У меня была аналогичная проблема с EF6. При использовании функции SqlQuery в EF я получил таймаут, хотя запрос был выполнен в миллисекундах в Management Studio. Я обнаружил, что это произошло из-за значения одного из параметров sql, которые я использовал в запросе EF. Чтобы было ясно, ниже приведен аналогичный SQL-запрос, с которым я столкнулся.

SELECT * FROM TBL WHERE field1 > @p1 AND field2>@p2 AND field3<@p3

Когда @p1 равно нулю, я получил исключение тайм-аута. Когда я сделал это 1 или что-то другое, оно было выполнено в миллисекундах. Кстати, таблица, на которую я запросила информацию, содержит более 20 М строк.

Надеюсь, это поможет, Лучший

Ответ 4

(DBCC FREEPROCCACHE)
DBCC DROPCLEANBUFFERS

теперь проблема исчезла, но я думаю, что это может быть просто темп. Решение

Ответ 5

Вам нужно добавить один столбец, который будет уникальным идентификатором или ключом, чтобы иметь возможность работать в EF