Obtener el plan de ejecución real de una consulta sin ejecutarla

Obtener el plan real es importante para medir el rendimiento de nuestras consultas y localizar problemas de rendimiento pero, el problema es que para ello necesitamos ejecutar la consulta, ¿o no?

La semana pasada hablamos del impacto de Query Store en el rendimiento de nuestros servidores. Veíamos que por norma general es prácticamente nulo pero, en casos concretos, con muchas consultas Ad Hoc podría llegar a ser un problema. Si está en uno de esos rarísimos casos donde los beneficios de Query Store no compensan su impacto en el rendimiento aun hay algo que vas a poder hacer para obtener el plan real de una consulta sin tener que llegar a ejecutarla. 

Obtener el plan real es importante para medir el rendimiento de nuestras consultas y localizar problemas de rendimiento pero, el problema es que para ello necesitamos ejecutar la consulta y esta puede ser costosa. Por suerte, desde SQL Server 2019 tenemos una alternativa. Para poder hacer uso de ella es necesario configurar adecuadamente el servidor para que almacene el plan real en lugar de solo el estimado. En este artículo profundizaremos en cómo lograrlo, lo que facilita el acceso a estos planes sin impacto en el sistema productivo.

Introducción a los Planes de Ejecución en SQL Server

Como ya hemos visto en varias ocasiones en el blog, un plan de ejecución representa la secuencia de operaciones que SQL Server realiza para ejecutar una consulta. Estos planes se pueden clasificar en dos tipos:

  • Estimados: SQL Server los calcula antes de ejecutar la consulta, basándose en estadísticas de los índices y distribuciones de datos.
  • Reales: Se generan después de ejecutar la consulta, reflejando los datos y operaciones reales ejecutadas, incluyendo métricas de tiempo y consumo de recursos.

La posibilidad de acceder a un plan de ejecución real sin re-ejecutar la consulta es especialmente valiosa en entornos de producción. SQL Server 2019 introdujo una funcionalidad para almacenar estos planes reales en caché, permitiendo su análisis sin la sobrecarga de una nueva ejecución.

¿Por qué vas a querer almacenar el plan real de las consultas?

Guardar el plan de ejecución real en lugar del estimado nos ofrece una visión precisa del rendimiento y consumo de recursos en tiempo de ejecución de una consulta, algo crucial para entornos de producción. A diferencia del plan estimado, que se basa en estadísticas previas, el plan real refleja las operaciones exactas que SQL Server ejecuta, incluyendo ajustes específicos de paralelismo, decisiones en el uso de índices y variaciones en la ejecución según los datos y los recursos disponibles. Esta precisión nos permite identificar cuellos de botella y problemas de optimización, como el parameter sniffing, donde SQL Server puede seleccionar un plan ineficiente basado en parámetros iniciales de la consulta.

Además, el plan real permite observar el impacto de condiciones específicas del sistema, como bloqueos y alta carga de CPU o memoria, brindándonos una comprensión completa del rendimiento bajo diferentes estados. En resumen, esta visibilidad detallada nos facilita la optimización continua, ya que podemos detectar patrones de rendimiento y ajustar el sistema o la consulta para mejorar la eficiencia sin necesidad de re-ejecutar la consulta. En conjunto, el acceso a planes reales convierte el análisis de rendimiento en un proceso más efectivo, permitiéndonos una gestión más precisa y proactiva del rendimiento del sistema SQL Server.

Almacenar en caché planes de ejecución reales

SQL Server nos permite almacenar el plan de ejecución real en la caché de planes, en lugar de solo el estimado. Esta configuración es especialmente útil para detectar problemas de rendimiento, ya que proporciona información precisa sin la necesidad de una segunda ejecución de la consulta. 

Para activar la traza globalmente en el servidor, podemos hacer uso de la traza 2451:

Donde 2451 es el número de la traza que permite almacenar el plan real y -1 establece que la traza se active a nivel global para todas las bases de datos y usuarios.

Nota: Activar la traza puede aumentar el uso de recursos del sistema, ya que SQL Server debe registrar información adicional para cada consulta que se ejecuta. Además, activar esta función requiere vaciar la caché de planes por lo que es recomendable activarlo solo si es estrictamente necesario y preferiblemente en ventanas de mantenimiento programadas o aprovechando una intervención de un reinicio del servicio.

Otra opción es activar esta característica a nivel de base de datos para que no se aplique a todo el servidor. En este caso, aunque los riesgos son los mismos vamos a poder minimizar el impacto. Para activarlo a nivel de base de datos usaremos el siguiente comando sobre la base de datos donde queramos cambiar la configuración.

Acceso al último plan de rjecución real

Una vez activada la traza o la configuración de base de datos, SQL Server almacenará los planes de ejecución reales en el caché de planes. Para acceder a ellos, utilizamos vistas de administración dinámica (DMVs) como sys.dm_exec_query_stats y sys.dm_exec_query_plan. Estas vistas nos proporcionan datos sobre las consultas y los planes almacenados en caché, permitiendo su análisis sin necesidad de re-ejecutar la consulta.

Ejemplo de consulta para obtener el último plan real

La siguiente consulta permite recuperar el último plan de ejecución real de las consultas en caché:

Esta consulta devuelve el campo query_text con el texto SQL de la consulta y el campo query_plan con el plan de ejecución en formato XML. Para ver el plan de ejecución gráfico, podemos hacer clic en el XML en SQL Server Management Studio (SSMS), lo cual nos permite analizar visualmente las operaciones ejecutadas, los índices utilizados y el costo relativo de cada operación.

Filtrado de una consulta específica

Si estamos buscando el plan de ejecución de una consulta en particular, es posible restringir los resultados usando un filtro en el texto de la consulta, lo cual facilita la identificación del plan específico entre todas las consultas en el caché:

Nota: A la hora de introducir parte del texto de la consulta que buscas en el filtro ten en cuenta que debe ser parte de la consulta (normalmente un nombre de una tabla o de un campo) pero nunca uno de los valores de los campos por los que estás filtrando ya que SQL Server remplaza esos valores por parámetros a la hora de almacenar el plan. 

Es decir, si quieres buscar la consulta “SELECT Campo1 FROM MiTabla WHERE Campo2=’tutifruti’;” podrás buscar por ‘%Campo1%’, ‘%Campo2%’ o ‘%MiTabla%’ pero no por ‘%tutifruti%’. Cuando encuentres el plan de ejecución vas a ver que lo que se ha guardado es algo parecido a esto “SELECT Campo1 FROM MiTabla WHERE Campo2=@0

Consideraciones Finales

La capacidad de acceder al último plan de ejecución real sin re-ejecutar la consulta es una capacidad poderosa para los DBAs, especialmente porque nos facilita la tarea de buscar problemas de rendimiento. Esta configuración nos ofrece un enfoque integral para monitorizar, analizar y optimizar el rendimiento de las consultas en entornos de producción sin comprometer la estabilidad del sistema. Sin embargo, aunque este enfoque nos permite detectar problemas de rendimiento con precisión y realizar ajustes informados para mejorar la eficiencia general del sistema para mi sigue siendo mejor la alternativa de Query Store donde vamos a poder ver todo el historial de planes de ejecución a lo largo del tiempo que hayamos definido y no solo el último plan real almacenado en caché.

Si tenéis alguna duda o sugerencia, podéis dejarla en Twitter, por mail o dejarnos un mensaje en los comentarios. Y recuerda que también tenemos un grupo de Telegram y un canal de YouTube a los que te puede unir. ¡Hasta la próxima!

Publicado por Roberto Carrancio

Mi nombre es Roberto Carrancio y soy un DBA de SQL server con más de 10 años de experiencia en el sector. Soy el creador del blog soydba.es donde intento publicar varios artículos a la semana (de lunes a viernes que los fines de semana me gusta estar con mi gente y disfrutar de mi moto) Espero que disfrutes leyendo este blog tanto como yo disfruto escribiendo y que te sea de utilidad. Si tienes alguna sugerencia, pregunta o comentario, puedes dejarlo al final de cada entrada o enviarme un correo electrónico. Estaré encantado de leerte y responderte. ¡Gracias por tu visita! Mi principal interés es compartir mi conocimiento sobre bases de datos con todo el que quiera aprenderlo. Me parece un mundo tan apasionante como desconocido. Fuera de lo profesional me encanta la cocina, la moto y disfrutar de tomar una cervecita con amigos.

Deja una respuesta