Surviving the Night

El blog de Pablo Doval sobre .NET, SQL, WinDbg...

Not Enough: El Query Governor en SQL Server 2005

Hace tiempo publiqué un post dedicado a mis amigos los DBAs, pero desde entonces no he dedicado ningún articulo dedicado en exclusiva a tareas de administración en entornos SQL Server. Esta carencia de posts no se debe a una aversión ciega a los DBAs por mi parte; de echo, les tengo un respeto enorme. Yo no podría sentarme día a día a realizar operaciones críticas en un servidor y aguantar la presión (principalmente porque soy muy torpe y despistado, como mi amigo el pezuñas, y si el se equivoca de botón, yo también puedo hacerlo).

Hoy voy a tratar de redimirme, de aportar algo a la comunidad de DBAs en su continua batalla con los usuarios... hoy quería hablaros de una herramienta muy poco conocida dentro de SQL Server: el Query Governor (música de suspense aqui, por favor...), que no es más que un mecanismo de control de ejecución de consultas pesadas. ¿Para que nos sirve esto? Veamos pues...

Un Escenario...

Imaginemos un escenario como el siguiente: tenemos un entorno transaccional tradicional que es atacado por una aplicación. Tanto la aplicación como la base de datos están bien dimensionadas para el uso diario y rutinario. Sin embargo, un buen día se decide implementar funcionalidad de reporting sobre la misma base de datos, ya que no hay presupuesto/tiempo/conocimientos para implementar un sistema de reporting paralelo. Se puede dar el caso que ciertas peticiones de informes se realicen sin problemas, mientras que algunos informes concretos, debido a la pesadez de las consultas subyacentes, nos dejen temblando el servidor, afectándonos al rendimiento de la operativa principal del sistema.

Si nos encontramos con este escenario, una posible solución es notificar a todos los usuarios que retrasen la ejecución de estos informes para horas de baja actividad del sistema... *carcajadas* ... Sabemos que esa no es una opción válida para un administrador; sabemos como son los usuarios, les conocemos bien :)

Una solución fantástica sería poder limitar el consumo de CPU y de memoria que puede emplea una consulta o grupo de consultas para su ejecución. ¡La buena noticia es que esa solución existe! La mala noticia es que no os voy a hablar de ella por ahora ;) Se trata de mi característica favorita de SQL Server 2008, conocida como el Resource Governor, y os hablaré de ella en un post próximo.

No obstante, antes quería escribir este post, que se basa en una solución intermedia, que consiste en cancelar la ejecución de una consulta cuyo consumo de CPU exceda un umbral predefinido. Esta solución no es tan elegante como la anterior, pero la ventaja es que la tenemos disponible en SQL Server 2000 y SQL Server 2005, con lo que podemos aplicarla a entornos actuales de producción.

Ahora que tenemos claro un escenario de ejemplo y la herramienta que vamos a utilizar, podemos pasar a describir al...

Query Governor

Siempre que pienso en el Query Governor me viene a la mente el retrato del Gobernador de Barbados, e historias de piratas, corsarios y la buena vida en Port Royal vienen a mi mente... pero lamentablemente la realidad es mucho más aburrida :(

El Query Governor, como hemos venido comentando, nos permite definir un umbral de tiempo de ejecución para nuestras consultas. Esto es, si la estimación del tiempo que va a durar una consulta es superior al valor definido como limite de tiempo en el Query Governor, esta consulta no llegará a comenzar su ejecución.

Para ver el valor actual, lo que debemos hacer es consultar el valor de los parámetros de configuración. Podemos hacerlo mediante la interfaz de usuario del SQL Server Management Studio, o mejor aún, mediante el procedimiento almacenado sp_configure. Como se trata de una opción avanzada, antes de poder visualizarla debemos habilitar las opciones avanzadas de configuración:

sp_configure 'show advanced options', 1
GO
RECONFIGURE
GO
sp_configure

Esto nos debería devolver la lista con todos los parámetros de configuración, entre los que se encontrará el query governor cost limit, que en mi caso vale 0 (el valor por defecto, que quiere decir que el Query Governor no está en uso).

Si alteramos el valor, podemos establecer el número de segundos máximos que otorgamos a la ejecución de cualquier consulta sobre toda la instancia. Podemos también establecer este parámetro a nivel de conexión, con el parametro SET query_governor_cost_limit, pero siendo realista ¿que cliente se va a poner restricciones a si mismo? :)

Vamos a escribir una consulta de ejemplo que resulte bastante pesada, por ejemplo la siguiente:

CREATE DATABASE PruebaQueryGovernor
GO
USE PruebaQueryGovernor
GO

CREATE TABLE dbo.Numeros
(
   Numero INT IDENTITY(1,1) PRIMARY KEY CLUSTERED
)
GO

WHILE COALESCE(SCOPE_IDENTITY(), 0) <= 100000
BEGIN
   INSERT dbo.Numeros DEFAULT VALUES
END

SELECT * FROM dbo.Numeros

Como se puede apreciar en el código, nos limitamos a crear una tabla auxiliar de números (viva la numeración!), en éste caso los primeros 100.000 números. La construcción de esta tabla tarda poco mas de 6 minutos en mi portátil, y bajo la configuración por defecto se ejecuta sin ningún problema. Vamos ahora a establecer un valor de umbral de tiempo de ejecución de, por ejemplo, 100 segundos:

sp_configure 'query governor cost limit', 100
RECONFIGURE

Ahora, si eliminamos la base de datos de prueba y volvemos a crear al tabla y a intentar poblarla, veremos que no se llega a realizar ninguna inserción, pues SQL Server determina que la consulta es demasiado pesada y la cancela antes de su ejecución. Ain't it fun? :)

Conclusiones

Hemos repasado el Query Governor al que tanto provecho le podemos sacar en nuestros despliegues actuales sobre SQL Server 2000 y SQL Server 2005, y de paso, he dejado caer un poquito de información acerca del Resource Governor de SQL Server 2008 para que la curiosidad os pueda... quiero creer que lo suficiente como para que todos juntos os estéis descargando como locos la última CTP de SQL Server 2008 para probar el Resource Governor, los servidores se colapsen, salga en los telediarios y en el programa de Ana Rosa y en el Sé lo que Hicisteis.... pero bueno, me conformaré con que al menos os despierte el interés suficiente como para leer el siguiente artículo :)

Rock Tip:

Como hemos visto en las conclusiones, el Query Governor de SQL Server 2005 es muy práctico, pero aún así it's not enough. 'Not Enough' es también el titulo de una balada/medio tiempo de Van Halen... bastante ñoña, todo hay que decirlo, pero no por ñoño, menos temazo... ojo... que en los Rock Tips del tio Doval solo aparecen temazos!.

En serio, si no la conocéis os recomiendo que le peguéis un orejazo; aunque no seas muy 'rockeros', este tema merece la pena :)

Posted: 20/12/2007 1:57 por Pablo Alvarez | con 5 comment(s)
Comparte este post:

Comentarios

DbRunas - Not Enough - El Query Governor en SQL Server 2005 ha opinado:

PingBack desde  DbRunas - Not Enough - El Query Governor en SQL Server 2005

# December 20, 2007 6:07 AM

Alberto ha opinado:

Suena muy interesante el tema del Resource Governor, ansío el artículo.

# December 20, 2007 2:13 PM

Mary Arcia ha opinado:

EXCELENTE INFORMACION....Aunque no me gustaria cancelar las consultas de los usuarios....pues ellos son los que al final mandan o no?

# December 21, 2007 3:17 PM

Pablo Alvarez ha opinado:

Iba a intercalar otro articulo antes de hablar del Resource Governor, pero viendo que hay interes en ello intentaré prioritizarlo :) Me alegro de saber que os interesa el tema!

Mary Arcia: Respecto a lo de que los usuarios son los que mandan... pues que quieres que te diga :) Yo personalmente no le dejaría a un usuario hacer un DROP de una base de datos, del mismo modo que no le dearía hacer una consulta pesada en un horario no apropiado.

Al punto de esto último, acabo de darme cuenta de que no he comentado en el artículo una solucion interesante: Podemos establecer el Query Governor solo en determinados horarios mediante un job del SQL Agent. De este modo, podriamos hacer algo como limitar la ejecución de consultas que estimen su duracion en mas de 500 segundos enter las 8:00am y las 20:00am, y eliminar esta restricción a partir de las 20:00am. De este modo estaríamos asegurandonos de que se cumple una restricción solo en una franja horaria dada.

No obstante, podemos tener mucha mas versatilidad con el Resource Governor de SQL Server 2008... pero eso será en otro post :)

# December 22, 2007 12:41 AM

Manuel Ayarza ha opinado:

Estimado estoy tratonado de limitar el numero de ejecucuiones de jobs pero encuentro donde se puede hacer en el sqlserver 2000

# August 23, 2010 6:10 PM