Fondo
Tengo una consulta en ejecución contra SQL Server 2008 R2 que une y / o une a la izquierda unas 12 "tablas" diferentes. La base de datos es bastante grande con muchas tablas de más de 50 millones de filas y unas 300 tablas diferentes. Es para una compañía grande que tiene 10 almacenes en todo el país. Todos los almacenes leen y escriben en la base de datos. Entonces es bastante grande y bastante ocupado.
La consulta con la que tengo problemas se parece a esto:
select t1.something, t2.something, etc.
from Table1 t1
inner join Table2 t2 on t1.id = t2.t1id
left outer join (select * from table 3) t3 on t3.t1id = t1.t1id
[etc]...
where t1.something = 123
Observe que una de las combinaciones está en una subconsulta no correlacionada.
El problema es que a partir de esta mañana, sin ningún cambio (que yo o cualquiera de mi equipo sepa) del sistema, la consulta, que generalmente demora aproximadamente 2 minutos en ejecutarse, comenzó a tardar una hora y media en ejecutarse, cuando corrió en absoluto. El resto de la base de datos está funcionando bien. Tomé esta consulta del sproc en el que generalmente se ejecuta y la ejecuté en SSMS con variables de parámetros codificadas con la misma lentitud.
Lo extraño es que cuando tomo la subconsulta no correlacionada y la tiro a una tabla temporal, y luego la uso en lugar de la subconsulta, la consulta funciona bien. Además (y esto es lo más extraño para mí) si agrego este código al final de la consulta, la consulta se ejecuta muy bien:
and t.name like '%'
Llegué a la conclusión (tal vez incorrectamente) de estos pequeños experimentos que la razón de la desaceleración se debe a cómo se configura el plan de ejecución en caché de SQL: cuando la consulta es un poco diferente, tiene que crear un nuevo plan de ejecución.
Mi pregunta es la siguiente: cuando una consulta que solía ejecutarse rápidamente, de repente comienza a ejecutarse lentamente en medio de la noche y nada más se ve afectado, excepto esta consulta, ¿cómo lo soluciono y cómo evito que suceda en el futuro? ? ¿Cómo sé qué está haciendo SQL internamente para hacerlo tan lento (si se ejecuta la consulta incorrecta, podría obtener su plan de ejecución pero no se ejecutará, ¿tal vez el plan de ejecución esperado me daría algo?)? Si este problema es con el plan de ejecución, ¿cómo evito que SQL piense que los planes de ejecución realmente malos son una buena idea?
Además, esto no es un problema con la detección de parámetros. Lo he visto antes, y esto no es así, ya que incluso cuando codifico los valores en SSMS, sigo obteniendo un rendimiento lento.