Estimado [su nombre aquí]!
¡Oh no, lamento escuchar eso! Comencemos con algunos conceptos básicos para arreglarlo en un santiamén.
La cosa con la que te encuentras se llama Parameter Sniffing
Es una forma de resolver el extraño problema. El nombre sale de la lengua. Como la palabra alemana para ardilla.
Y generalmente es tu amigo.
Cuando una consulta llega a su servidor, se debe compilar un plan. Para ahorrar tiempo y recursos más adelante, se almacena en caché un plan de ejecución basado en las filas estimadas que harán que su código procese y regrese.
La forma más fácil de imaginar que esto va mal es imaginar un procedimiento almacenado que necesite contar cosas de dos poblaciones asimétricas.
Por ejemplo:
Obviamente, una ejecución de ese código tendría que hacer mucho más trabajo que otra, y los planes de consulta que desearía realizar cantidades de trabajo totalmente diferentes se verían totalmente diferentes.
¿A qué me enfrento?
Este es un problema realmente difícil de encontrar, probar y solucionar.
- Es difícil de encontrar porque no sucede constantemente
- Es difícil de probar porque necesita saber qué parámetros causan diferentes planes
- Es difícil de solucionar porque a veces requiere consultas y ajuste de índice
- Es difícil de solucionar porque es posible que no pueda cambiar consultas o índices
- Es difícil de solucionar porque incluso si cambia las consultas o los índices, aún podría volver
Arreglos rápidos
A veces, todo lo que necesitas es un poco de claridad. O más bien, su caché del plan lo hace.
Si es un procedimiento almacenado
Intenta correr EXEC sys.sp_recompile @objname = N'schema.procname'
. Eso hará que el procedimiento recompile un nuevo plan la próxima vez que se ejecute.
Lo que esto no solucionará:
- Procesos que actualmente lo ejecutan.
Lo que esto no garantiza:
- El siguiente proceso que se ejecuta después de la recompilación utilizará un parámetro que le dará un buen plan.
También puede apuntar sp_recompile
a una tabla o vista, pero tenga en cuenta que todo el código que toque esa tabla o vista se recompilará. Esto podría hacer que el problema sea mucho más difícil.
Si es una consulta parametrizada
Tu trabajo es un poco más difícil. Deberá localizar el controlador SQL. No desea liberar todo el caché del plan; al igual que si se usa sp_recompile
contra una tabla o vista, podría desencadenar (ja, ja, ja) un montón de consecuencias no deseadas.
La forma más fácil de resolver ese comando es ejecutar sp_BlitzWho *! Hay una columna llamada "sniffing de parámetros fijos" que tiene un comando para eliminar un solo plan del caché. Sin embargo, esto tiene los mismos inconvenientes que la recompilación.
Lo que esto no solucionará:
- Procesos que actualmente lo ejecutan.
Lo que esto no garantiza:
- El siguiente proceso que se ejecuta después de la recompilación utilizará un parámetro que le dará un buen plan.
¡Todavía necesito ayuda!
Vamos a necesitar lo siguiente:
- El buen plan de consulta, si es posible
- El mal plan de consulta
- Los parámetros utilizados
- La consulta en cuestión
- Definiciones de tabla e índice
Obtener los planes de consulta y consulta
Si la consulta se está ejecutando, puede usar sp_BlitzWho * o sp_WhoIsActive para capturar las consultas que se están ejecutando actualmente.
EXEC sp_BlitzWho;
EXEC sp_WhoIsActive @get_plans = 1;
Si la consulta no se está ejecutando actualmente, puede verificarla en la caché del plan, usando sp_BlitzCache *.
Si tiene SQL Server 2016+ y tiene activado el Almacén de consultas, puede usar sp_BlitzQueryStore *.
EXEC dbo.sp_BlitzCache @StoredProcName = 'Your Mom';
EXEC dbo.sp_BlitzQueryStore @StoredProcName = 'Your Mom';
Esto lo ayudará a rastrear las versiones en caché de su Procedimiento almacenado. Si solo se trata de un código parametrizado, su búsqueda es un poco más difícil. Sin embargo, esto puede ayudar:
EXEC dbo.sp_BlitzCache @QueryFilter = 'statement';
Debería ver una salida bastante similar de cualquiera de esos. Una vez más, el plan de consulta que invita a la columna de clic azul es tu amigo.
La forma más fácil de compartir planes es usar Pegar el plan * o volcar el XML en pastebin. Para obtener eso, haga clic en cualquiera de esas atractivas columnas azules clicky. Su plan de consulta debería aparecer en una nueva pestaña SSMS.
Si le preocupa compartir el código y la consulta de su empresa, puede usar la herramienta gratuita Plan Explorer de Sentry One para anonimizar su plan. Tenga en cuenta que esto hace que obtener ayuda sea más difícil: el código anónimo es mucho más difícil de leer y resolver.
Todas estas herramientas de las que hablamos deberían devolver el Texto de consulta. No necesitas hacer nada más aquí.
Obtener los parámetros es un poco más difícil. Si está utilizando Plan Explorer , hay una pestaña en la parte inferior que los enumera todos por usted.
Si está utilizando sp_BlitzCache *, hay una columna en la que se puede hacer clic que le proporciona la instrucción de ejecución para los procedimientos almacenados.
Obtener las definiciones de tabla e índice
Puede hacer clic con el botón derecho en SSMS para escribir las cosas.
Si desea obtener todo de una vez, sp_BlitzIndex * puede ayudarlo si lo apunta directamente a una mesa.
EXEC dbo.sp_BlitzIndex @DatabaseName = 'StackOverflow2010',
@SchemaName = 'dbo',
@TableName = 'Users';
Esto le dará la definición de la tabla (aunque no como una declaración de creación) y creará declaraciones para todos sus índices.
Recopilar y agregar esta información a su pregunta debería brindarle a la gente suficiente información para ayudarlo o orientarlo en la dirección correcta.
¡Quiero hacerlo yo mismo!
Bueno, genial Estoy feliz por ti. Eres un loco.
Hay muchas maneras en que las personas piensan que "arreglan" la detección de parámetros:
Pero estos realmente solo deshabilitan el rastreo de parámetros de diferentes maneras. Eso no quiere decir que no puedan resolver el problema, simplemente no llegan a la causa raíz.
Eso se debe a que llegar a la causa raíz suele ser un poco difícil. Tienes que buscar esos molestos "problemas de calidad del plan".
Comenzando con los planes rápido versus lento, busque diferencias como:
- Índices utilizados
- Orden de unión
- Serie vs Paralelo
También busque diferentes operadores que hagan que su código sea sensible al rastreo de parámetros:
- Búsquedas
- Ordena
- Tipo de unión
- Concesiones de memoria (y por extensión, derrames)
- Carretes
No se deje envolver demasiado en la búsqueda contra el escaneo, la fragmentación del índice ni ninguna de las cosas de culto de la carga que la gente dobla y habla.
Por lo general, hay un problema de indexación bastante básico. A veces el código necesita una pequeña reescritura.
Si desea obtener más información sobre la detección de parámetros:
Si estás leyendo esto y crees que me perdí un enlace o una herramienta útil, deja un comentario. Haré todo lo posible para mantener esto actualizado.