Pues sí. En ocasiones ocurre. Ya sea por aplicaciones que no estén muy bien optimizadas (en lo relacionado al acceso a la base de datos, indexación, diseño del modelo de datos, etc.), ya sea por consolidar en una única instancia de SQL Server demasiadas bases de datos sin un estudio apropiado previo (encontrándonos con fuertes cargas de trabajo que se solapan), ya sea por cargas excepcionales de trabajo (procesos de cierre de fin de mes), etc.
El caso, es que cuando nos ocurre en nuestras máquinas, en las máquinas que conocemos y con las que trabajamos en el día a día, muchas veces no nos será necesario ni mirar en SQL Server qué ocurre para tenerlo claro. Sin embargo, cuando se trata de máquinas que no conocemos mucho, o incluso en máquinas que conocemos pero que han estado sujetas a recientes cambios de IT o de sus aplicaciones, no surgirá la duda, y nos resultará necesario saber quién se está llevando la CPU de SQL Server, como primer paso para poder diagnosticar la existencia o no de Problemas de Rendimiento en SQL Server.
Podemos consultar la información de los SPIDs en sys.sysprocesses, pero el hecho de que puedan existir aplicaciones que trabajen orientadas a la conexión u orientadas a la desconexión, hace que no resulte tan trivial su interpretación. Recordemos, que una aplicación que trabaja orientada a la conexión, establecerá una conexión a la base de datos, y la mantendrá constantemente, enviando a través de dicha conexión multitud de peticiones, conforme le resulte necesario (ojo, algunas aplicaciones mantienes varias conexiones, cada una de ellas orientada a la conexión). Sin embargo, una aplicación que trabaja orientada a la desconexión, tenderá a mantenerse desconectada de la base de datos, y para cada petición que necesite realizar, creará una conexión a la base de datos para ejecutar dicha petición y seguidamente desconectarse (eso sí, habitualmente, utilizando Pool de Conexiones).
Una forma casera y poco precisa de poder obtener la información del consumo reciente de CPU en SQL Server, consiste en consultar el contenido de sys.sysprocesses varias veces seguidas, separadas por una cantidad de tiempo fija (ej: cada segundo, utilizando WAITFOR DELAY), y con dicha información, intentar obtener el reparto del consumo reciente de la CPU, tanto por SPID como por Base de Datos. Por ejemplo, si tenemos un SPID que aparece en las diferentes consultas realizadas a sys.sysprocesses, podemos estimar su consumo de CPU en este periodo de tiempo, como resultado de restar al valor MAX de CPU el valor MIN de CPU de este SPID.
Insisto en que se trata de un proceso casero y susceptible de errores, pero en alguna ocasión me ha resultado de bastante utilidad (aún con sus deficiencias) para un primer vistazo, por lo que quería aprovechar para compartirlo, para quién le pueda resultar de utilidad.
Por poner un ejemplo de los puntos débiles de este sistema casero, el hecho de utilizar WAITFOR para tomar muestras de sysprocesses cada segundo, puede implicar que muchas conexiones de aplicaciones que trabajan orientadas a la desconexión, no podamos cazarlas, ya que lo lógico es que dichas conexiones tarden menos de un segundo (que ya de por sí, es una barbaridad) en ejecutarse. Aún así, en este caso, si dicha aplicación orientada a la desconexión estuviese generando una gran cantidad de conexiones a SQL Server, deberíamos poder observarlo con este Script, aún a sabiendas de que nos faltarán conexiones, más aún si la máquina está saturada al 100% de CPU (en este caso, todo empezará a ir más lento, aumentando la probabilidad de que cacemos más consultas en cada muestra, al aumentar el tiempo de ejecución de cada consulta por la ausencia de suficientes recursos).
Tiene más puntos débiles, pero bueno, tampoco voy a autoputearme gratuitamente. Digo yo que también habrá que ver lo positivo.
A continuación se incluye el Script comentado, el cual utiliza una tabla temporal en la que almacenar las diferentes ejecuciones de consultas sobre sys.sysprocesses, y finalmente incluye un par de consultas sobre dicha tabla temporal, para obtener información del consumo de CPU por proceso, e información del consumo de CPU por base de datos. La tabla temporal se borra al principio del Script, de tal modo, que si una vez ejecutado el Script necesitamos consultar la información de la tabla temporal, aún estará disponible para nosotros. Al principio del Script tenemos un par de variables, en las que parametrizar el número de muestras que deseamos tomar, y cada cuanto tiempo las deseamos tomar (que sea en múltiplos de un segundo, ya que con fracciones inferiores, el WAITFOR DELAY se interpretará como WAITFOR DELAY 0, es decir, sin separación temporal entre cada muestra). Este Script permite comprobar el consumo de CPU en SQL Server 2008, SQL Server 2005 y SQL Server 2000.