En Solid Quality estamos realizando una serie de Summits por Latam (http://learning.solidq.com/la/CourseDetail.aspx?CourseScheduleId=211). El viernes pasado tuvimos el primero en Costa Rica, y próximamente estaremos en México, Colombia y Perú. Aunque no presencialmente, tengo la suerte de haber sido invitado a estos eventos como ponente. Me encuentro en España, y a través de Livemeeting, puedo contar a los asistentes a los Summits mis experiencias desde mi hogar en Torrevieja 

Bueno, el tema es que este viernes, tuve la primera presentación, y aunque la presentación estaba focalizada en SQL Server 2005:

“SQL Server: Optimización y Afinamiento de servidores SQL Server: Al atender esta sesión, brindaremos las mejores prácticas para el análisis de rendimiento de servidores de bases de datos SQL Server 2005. Aprenderá a monitorear el uso de los recursos de su servidor (procesador, memoria, unidades IO, …) y mediante nuevas funciones de administración (DMVs), SQL Profiler y Performance Monitor mostraremos como identificar las consultas que más impacto tienen en su sistema para atacar los problemas de rendimiento desde su raíz. Muchas de las prácticas que presentaremos son aprendidas directamente del equipo que desarrolló el producto.”

 Estuve haciendo bastantes referencias a SQL Server 2000 porque:

·        Muchos de los asistentes trabajan con SQL Server 2000.

·        Nuestra experiencia en clientes dice que todavía hay muchos clientes con SQL Server 2000.

El mismo artículo lo tengo publicado para SQL Server 2005 en las siguientes URLs:

https://blogs.solidq.com/ES/erincon/Lists/Posts/Post.aspx?ID=28

http://solidqualitylearning.com/Blogs/eladio/archive/2007/02/22/3727.aspx

Me comprometí con los asistentes a publicar el mismo script para SQL Server 2000, así que ahí va:

 

El procedimiento almacenado

Para vuestra información he tenido que realizar los siguientes cambios:

  • Quitar referencia a CTE (obviamente en SQL Server 2000 no existe).
  • Quitar referencia a DMV y utilizar el correspondiente comando DBCC.
  • Cambiar tabla variable por tabla temporal porque un comando DBCC no puede insertar en una tabla variable.
  • Filtrar del resultado del comando DBCC el wait_type “Total” que es la suma total de los valores medidos.

Ejemplo de ejecución:

EXEC dbo.sproc_get_waitstats_percentage

     @hours = null,

     @minutes  = 5,

     @seconds  = null

 

El procedimiento almacenado:

IF EXISTS (SELECT * FROM sysobjects WHERE name = ‘sproc_get_waitstats_percentage’)

  DROP PROC dbo.sproc_get_waitstats_percentage

GO

 

CREATE PROC dbo.sproc_get_waitstats_percentage

     @hours tinyint = null,

     @minutes  tinyint = null,

     @seconds  tinyint = null

AS

 

SET NOCOUNT ON

 

IF @hours IS NULL

     SET @hours = 0

IF @minutes IS NULL

     SET @minutes = 0

IF @seconds IS NULL

     SET @seconds = 0

 

— Validaciones iniciales

IF @hours < 0 OR @hours > 24

BEGIN

   RAISERROR (‘Hours range is not valid.’, 16, 1 )

   RETURN

END

 

IF @minutes < 0 OR @minutes > 60

BEGIN

   RAISERROR (‘Minutes range is not valid.’, 16, 1 )

   RETURN

END

 

IF @seconds < 0 OR @seconds > 60

BEGIN

   RAISERROR (‘Seconds range is not valid.’, 16, 1 )

   RETURN

END

 

IF @hours = 0 and @minutes = 0 and @seconds = 0

BEGIN

   RAISERROR (‘The measure time must be greater than zero.’, 16, 1 )

   RETURN

END

 

— Definición de variable table

CREATE TABLE #T (

id int identity

, wait_type nvarchar(60)

, Requests bigint

, Wait_Time bigint

, signal_Wait_Time bigint)

 

— Inserción de captura inicial

INSERT #T

EXEC (‘DBCC SQLPERF(WAITSTATS)’)

 

— A esperar n tiempo

DECLARE @s CHAR(8)

SET @s =

      RIGHT (’00’ + CAST (@hours as VARCHAR(2)), 2) + ‘:’

     + RIGHT (’00’ + CAST (@minutes as VARCHAR(2)), 2) + ‘:’

     + RIGHT (’00’ + CAST (@seconds as VARCHAR(2)), 2)

 

WAITFOR DELAY @s

 

— Inserción de segunda captura

INSERT #T

EXEC (‘DBCC SQLPERF(WAITSTATS)’)

 

— calculos finales

SELECT

     detalle.*

     , detalle.Wait_Time * 1.00 / detalle.Requests as wait_per_request

     , CASE WHEN suma.Requests = 0 THEN 0 ELSE detalle.Requests * 1.00 / suma.Requests END as porcen_Requests

     , CASE WHEN suma.Wait_Time = 0 THEN 0 ELSE detalle.Wait_Time * 1.00 /  suma.Wait_Time END as porcen_Wait_Time

     , CASE WHEN suma.signal_Wait_Time = 0 THEN 0 ELSE detalle.signal_Wait_Time * 1.00 /  suma.signal_Wait_Time END as porcen_signal_Wait_Time

FROM

(SELECT * FROM ( SELECT

     T1.wait_type

     , AVG(T2.Requests T1.Requests) Requests

     , AVG(T2.Wait_Time T1.Wait_Time) Wait_Time

     , AVG(T2.signal_Wait_Time T1.signal_Wait_Time) signal_Wait_Time

FROM #T t1

JOIN #T t2

  ON T1.wait_type = T2.wait_type

 AND T1.id < T2.id

WHERE T1.wait_type <> ‘Total’

GROUP BY T1.wait_type

) v WHERE

v.Wait_Time <> 0

) detalle,

( SELECT

     SUM (T2.Requests T1.Requests) Requests

     , SUM (T2.Wait_Time T1.Wait_Time) Wait_Time

     , SUM (T2.signal_Wait_Time T1.signal_Wait_Time) signal_Wait_Time

FROM #T t1

JOIN #T t2

  ON T1.wait_type = T2.wait_type

 AND T1.id < T2.id

WHERE T1.wait_type <> ‘Total’

) suma

 

GO

 

Siéntete libre de publicar comentarios…

 

Eladio Rincón