¿Cuáles son las razones por las que falta un plan de la memoria caché para los procedimientos almacenados?
WITH RECOMPILE
- SQL dinámico
- Código encriptado
- Cambios significativos de datos
- Actualizar estadísticas
- ¿Qué más?
Recientemente trabajé en 2 servidores (SQL Server 2008 R2 y SQL Server 2012) que no tenían planes en caché para procedimientos almacenados que requieren muchos recursos. Muchas, tal vez todas, las declaraciones dentro de los procedimientos almacenados tampoco tenían planes en caché. Algunos de los procedimientos almacenados se ejecutan con bastante frecuencia, como algunas veces por segundo.
No hay presión de memoria en absoluto. Uno de los servidores tiene mucho más hardware del necesario.
Pensé que los planes faltantes se debían a creaciones de tablas temporales en el medio de los procedimientos almacenados, pero esa parece ser información antigua de SQL Server 2000 o anterior. A partir de SQL Server 2005, las recompilaciones suceden en el nivel de instrucción para las instrucciones después del DDL. ¿Es eso cierto en todos los casos o todavía puede suceder en versiones más recientes?
¿Qué más podría ser el culpable de los planes faltantes? He leído algunos artículos sobre este tema, pero nada parece encajar.
Optimizar para cargas de trabajo ad hoc está habilitado en el servidor que estoy viendo esta semana. Uno de los procedimientos almacenados solo se ejecuta una vez al día. Tengo el código para ese. No tengo el código para el que se ejecuta más de 100 veces por minuto, pero puedo obtenerlo. No podré publicar el código, pero puedo describirlo en relación con mi pregunta.
No creo que nadie esté liberando el caché del procedimiento o dejando caer buffers limpios. Este cliente está utilizando Solarwinds DPA como una de sus herramientas de monitoreo. DPA capturó uno de los planes de ejecución de la declaración en el proceso almacenado que se llama una vez al día. Esa declaración tiene una gran cantidad de lecturas debido a una WHERE
cláusula no sargable . Si DPA capturó la declaración, entonces es un plan estimado y estuvo en el caché del plan al mismo tiempo. Simplemente no está allí cuando estamos solucionando problemas. Haré que inicien sesión sp_WhoIsActive
en una mesa.
Estoy usando sp_BlitzCache
. (Trabajo para Brent Ozar Unlimited) Esto mostrará el plan para todo el procedimiento almacenado, así como los planes para las declaraciones individuales, si existen. Si no existen, tiene esto como advertencia "No pudimos encontrar un plan para esta consulta. Las posibles razones para esto incluyen SQL dinámico, RECOMPILE
sugerencias y código cifrado". Y esa advertencia también está en las declaraciones.
TF 2371 no está en su lugar. Estoy mirando las estadísticas de espera. El servidor está bastante aburrido. PLE es más de 130,000.
Ahora tengo el código para 2 procedimientos almacenados más. Uno de ellos está utilizando SQL dinámico con el exec (@sql)
que sabemos por qué no hay un plan para ello. Pero el otro, y este es el que se ejecuta más de 100 veces por minuto, no tiene nada fuera de lo común. Lo único que se destaca en eso es que las tablas temporales se están creando en medio de más de 1000 líneas de código. También llama a un montón de procedimientos almacenados secundarios.
Con respecto al plan de almacenamiento en caché en SQL Server 2008 , no veo literales> = 8k, pero uno de los procedimientos almacenados tiene un comentario sobre una inserción masiva justo antes de llamar a otro procedimiento almacenado. Pero la inserción masiva no aparece en el procedimiento almacenado externo que estoy viendo. La sección "Umbral de recompilación" del artículo es interesante. Lo que veo para las tablas temporales son toneladas de INSERTOS (que podrían generar millones de filas), algunas actualizaciones y eliminaciones. Así que muchos cambios de datos en las tablas temporales. Millones
fuente
Respuestas:
Hay dos DMF de caché del plan:
sys.dm_exec_query_plan : devuelve planes almacenados en caché en formato XML, pero solo hasta cierto tamaño (y solo mientras puedan formatearse como XML en SQL Server, lo que significa hasta 128 niveles anidados).
sys.dm_exec_text_query_plan : devuelve planes en caché en formato de texto, de cualquier tamaño. Pero el inconveniente es que cuando los planes son grandes, no puede convertirlos a XML dentro de SQL Server, e incluso TRY_CONVERT ya que XML devuelve un valor nulo.
sp_BlitzCache solo llega al DMV anterior (porque necesita analizar los planes de consulta como XML para hacer todo tipo de corte y corte en cuadritos). Realicé el problema # 838 de Github para mejorar esto, por lo que al menos podríamos alertar a los usuarios para que revisen sys.dm_exec_text_query_plan para ver si consultas más grandes Sin embargo, aún no podremos hacer análisis XML en él.
fuente
sys.query_store_plan.query_plan
esnvarchar(MAX)
, no XML (trivia SQL).¿Posiblemente necesite ajustar el tamaño máximo del XML que SSMS puede devolver a una cuadrícula?
fuente