У меня есть Entity Framework 4.1 с .NET 4.5, работающий на ASP.NET в Windows 2008R2. Я использую EF-код для подключения к SQL Server 2008R2 и выполнения довольно сложного запроса LINQ, но в результате получается только Count()
.
Я воспроизвел проблему на двух разных веб-серверах, но только с одной базой данных (производство, конечно). Он недавно начал происходить без приложения, структуры базы данных или изменений сервера в Интернете или на стороне базы данных.
Моя проблема заключается в том, что выполнение запроса при определенных обстоятельствах занимает смехотворное количество времени (около 4 минут). Я могу взять фактический запрос, извлечь из SQL Profiler и выполнить в SSMS примерно через 1 секунду. Это непротиворечиво и воспроизводимо для меня, но если я изменил значение одного из параметров (параметр "Дата после 2015-01-22" ) на что-то раньше, например 2015-01-01 или позже, как 2015-02- 01, он отлично работает в EF. Но я вернул его к 2015-01-22 годам, и он снова замедлился. Я могу повторять это снова и снова.
Затем я могу запустить аналогичный, но несвязанный запрос в EF, а затем вернуться к оригиналу, и на этот раз он отлично работает - тот же самый точный запрос, что и раньше. Но если я открою новый браузер, цикл начнется снова. Эта часть также не имеет смысла - мы ничего не делаем, чтобы сохранить контекст данных в пользовательском сеансе, поэтому я не знаю, почему это происходит.
Но это все говорит мне, что сами данные в порядке.
В Profiler, когда запрос выполняется правильно, он занимает около секунды или два, и показывает около 2 000 000 в чтениях и около 2000 в CPU. Когда он работает медленно, это занимает 3,5 минуты, а значения - 300 000 000 и 200 000 - поэтому чтение примерно в 150 раз выше, а процессор в 100 раз выше. Опять же, для идентичного оператора SQL.
Любые предложения по поводу того, что EF может делать по-другому, что не будет отображаться в тексте запроса? Есть ли какое-то скрытое свойство соединения, которое может привести к другому плану выполнения при определенных обстоятельствах?
ИЗМЕНИТЬ
Запрос, который создает EF, является одним из тех, где он строит гигантскую строку с параметром, включенным в текст, а не как параметр SQL:
exec sp_executesql
N'SELECT [GroupBy1].[A1] AS [C1]
FROM (
SELECT COUNT(1) AS [A1]
...
AND ([Extent1].[Added_Time] >= convert(datetime2, ''2015-01-22 00:00:00.0000000'', 121))
...
) AS [GroupBy1]'
ИЗМЕНИТЬ
Я не добавляю это как ответ, так как на самом деле он не затрагивает основную проблему, но в конечном итоге ее устраняют путем восстановления индексов и статистики перекомпоновки. Это было сделано не дольше, чем обычно, и, похоже, выяснилось, что вызвало проблему.
Я продолжу читать некоторые ссылки здесь, если это произойдет снова, но поскольку все это работает сейчас и не подлежит восстановлению, я не знаю, смогу ли я когда-либо точно знать, что он делает.
Спасибо за все идеи.