Faltan planes de ejecución para procedimientos almacenados


12

¿Cuáles son las razones por las que falta un plan de la memoria caché para los procedimientos almacenados?

  1. WITH RECOMPILE
  2. SQL dinámico
  3. Código encriptado
  4. Cambios significativos de datos
  5. Actualizar estadísticas
  6. ¿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 WHEREclá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_WhoIsActiveen 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, RECOMPILEsugerencias 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


Como tiene los procs almacenados que reproducen el problema, ¿puede crear un ejemplo mínimo que lo repros y al hacerlo descubra el problema?
Martin Smith

Respuestas:


3

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.


Y también la misma razón sys.query_store_plan.query_planes nvarchar(MAX), no XML (trivia SQL).
Remus Rusanu

@RemusRusanu ooo, ¡así que grandes planes aparecen allí! Agradable.
Brent Ozar

Estamos verificando si los planes faltantes se deben a lo que encontró. Tan pronto como tenga noticias, publicaré una actualización.
Tara Kizer

Estoy marcando esto como la respuesta a pesar de que no he tenido noticias del cliente. Es lo único que queda y podría tener sentido dadas las enormes consultas. Publicaré una actualización si algo cambia.
Tara Kizer

@TaraKizer solo estás haciendo esto porque tu revisión trimestral está por venir, ¿verdad? Veo lo que hiciste alli. BONIFICACIÓN DESBLOQUEADA.
Brent Ozar

0

¿Posiblemente necesite ajustar el tamaño máximo del XML que SSMS puede devolver a una cuadrícula?


No, porque, como observa Tara, incluso si lo escribe en una tabla y verifica la longitud allí, no se devuelven datos.
Brent Ozar
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.