Я сталкиваюсь с некоторыми серьезными проблемами производительности с простыми SQL-запросами, сгенерированными Entity Framework (4.2), работающими с SQL Server 2008 R2. В некоторых ситуациях (но не во всех) EF использует следующий синтаксис:
exec sp_executesql 'DYNAMIC-SQL-QUERY-HERE', @param1...
В других ситуациях просто выполняется необработанный SQL с предоставленными параметрами, запеченными в запросе. Проблема, с которой я сталкиваюсь, заключается в том, что запросы, выполняемые с помощью sp_executesql, игнорируют все индексы в моих целевых таблицах, что приводит к чрезвычайно плохому выполнению запроса (подтверждается путем изучения плана выполнения в SSMS).
После небольшого исследования, похоже, проблема может быть вызвана "параметризацией". Если я добавлю подсказку запроса OPTION (RECOMPILE) следующим образом:
exec sp_executesql 'DYNAMIC-SQL-QUERY-HERE OPTION(RECOMPILE)', @param1...
Используются индексы в целевых таблицах, и запрос выполняется очень быстро. Я также попытался переключиться на флаг трассировки, используемый для отключения параметра sniffing (4136) в экземпляре базы данных (http://support.microsoft.com/kb/980653), однако, похоже, это не было любой эффект.
Это оставляет мне несколько вопросов:
- Есть ли способ добавить подсказку запроса OPTION (RECOMPILE) к SQL, сгенерированному Entity Framework?
- Есть ли способ предотвратить использование Entity Framework для использования exec sp_executesql, а вместо этого просто запустить необработанный SQL?
- Кто-нибудь еще сталкивается с этой проблемой? Любые другие подсказки/подсказки?
Дополнительная информация:
- Я перезапустил экземпляр базы данных через SSMS, однако я попробую перезапустить службу с консоли управления сервисами.
- Параметризация установлена на SIMPLE (is_parameterization_forced: 0)
- Оптимизация для рабочих нагрузок adhoc имеет следующие настройки:
- значение: 0
- минимум: 0
- максимум: 1
- value_in_use: 0
- is_dynamic: 1
- is_advanced: 1
Я также должен упомянуть, что если я перезапущу службу SQL Server через консоль управления сервисом ПОСЛЕ того, как включить флаг трассировки 4136 с ниже script, на самом деле очистит флаг трассировки... возможно, я должен делать это другим способ...
DBCC TRACEON(4136,-1)