Estoy teniendo algunos problemas importantes de rendimiento con consultas SQL simples generadas por Entity Framework (4.2) ejecutándose en SQL Server 2008 R2. En algunas situaciones (pero no todos), EF utiliza la siguiente sintaxis:Entity Framework 4.2 exec sp_executesql no utiliza índices (detección de parámetros)
exec sp_executesql 'DYNAMIC-SQL-QUERY-HERE', @param1...
En otras situaciones es simplemente ejecuta el SQL crudo con los parámetros proporcionados al horno en la consulta. El problema que encuentro es que las consultas ejecutadas con sp_executesql ignoran todos los índices en mis tablas de destino, lo que resulta en una consulta de rendimiento extremadamente pobre (confirmada al examinar el plan de ejecución en SSMS).
Después de un poco de investigación, parece que el problema podría ser causado por el "olfato de parámetros". Si añado la indirecta OPCIÓN (RECOMPILE) consulta de este modo:
exec sp_executesql 'DYNAMIC-SQL-QUERY-HERE OPTION(RECOMPILE)', @param1...
Los índices en las tablas de destino se utilizan y la consulta se ejecuta de forma extremadamente rápida. También intenté alternar en el indicador de rastreo utilizado para desactivar el rastreo de parámetros (4136) en la instancia de la base de datos (http://support.microsoft.com/kb/980653), sin embargo, esto no pareció tener ningún efecto en absoluto.
Esto me deja con algunas preguntas:
- todos modos hay que añadir el toque OPCIÓN (RECOMPILE) consulta al SQL generado por Entity Framework?
- ¿Hay alguna forma de evitar que Entity Framework use exec sp_executesql, y simplemente ejecute el SQL sin formato?
- ¿Alguien más tiene este problema? ¿Alguna otra pista/sugerencia?
Información adicional:
- hice reiniciar la instancia de base de datos a través de SSMS, sin embargo, voy a tratar de reiniciar el servicio desde la consola de administración de servicios.
- Parametrización se establece en simples (is_parameterization_forced: 0)
- Optimizar para cargas de trabajo ad hoc tiene los siguientes valores
- valor: 0
- mínimo: 0
- máxima: 1
- value_in_use: 0
- is_dynamic: 1
- is_advanced: 1
Debo mencionar también que si reinicio el servicio de SQL Server a través de la consola de gestión del servicio DESPUÉS de habilitar el indicador de traza 4136 con la siguiente secuencia de comandos, parece borrar la marca de traza ... quizás debería estar haciendo esto de manera diferente ...
DBCC TRACEON(4136,-1)
No puedo responder nada sobre EF (lo siento, nunca lo he tocado), pero tengo otras preguntas que debe responder en su pregunta: ¿Reinició el servicio después de configurar el indicador de seguimiento? ¿Cuál es su configuración en el nivel de la base de datos para la parametrización (simple o forzada, consulte 'sys.databases.is_parameterization_forced')? ¿Cuál es la configuración sp_configure para "optimizar para cargas de trabajo ad hoc"? Desafortunadamente, si no recuerdo mal, EF creará dos planes diferentes para parámetros como N'foo 'y N'blat', porque son longitudes diferentes. –
¡Mis disculpas por la respuesta tardía y gracias por su rápido comentario! He agregado la información adicional a la publicación original. – mindlessgoods
Así que volvería a probar las pruebas con (a) parametrización establecida en forzada (b) optimize para cargas de trabajo ad hoc establecidas en 1 y (c) ambas. Es bastante probable que (b) ayude a este escenario pero (a) también podría ayudar. Confieso que no probé mucho con (a) pero (b) he ayudado con todas las cargas de trabajo ad hoc que he probado. –