T-SQL expande el estándar de SQL para incluir programación procedural, variables locales, varias funciones de soporte para procesamiento de strings, procesamiento de fechas, matemáticas, etc, y cambios a los estatutos DELETE y UPDATE

Nivel de Fragmentacion de una base de dato

Nivel de Fragmentación

Uno de los principales tópicos que se debe verificar es el crecimiento de los archivos que componen una base de datos, como así también el nivel de fragmentación de los índices que la componen.

Asegurar el mejor rendimiento de una base de datos en MSSQL Server puede ser una tarea labiosa.

Verifica que bases de datos crecieron de manera automática

Cuando alguno de los archivos que componen la base (mdf y ldf) se queden sin espacios, y tiene permitido autocrecer (autogrowth) detienen la consulta en curso,  y autoincrementa su tamaño, y continua con la operación inicial. Esto si ocurre muy seguido puede provocar que se reduzca el rendimiento de la base.
Una forma de detectarlo es consultando el log del SQL Server:

SELECT
DatabaseName as Base,
[FileName] as Archivo,
CASE EventClass
			WHEN 92 THEN 'Datos'
			WHEN 93 THEN 'Log'
END  as Tipo,
CONVERT(VARCHAR(20), EndTime - StartTime, 114) as TiempoDemora,
StartTime as FechaInicio,
EndTime as FechaFin
 

FROM (
SELECT pt = REVERSE(SUBSTRING(REVERSE([path]), CHARINDEX('\', REVERSE([path])), 260)) + N'log.trc'
FROM sys.traces
WHERE is_default = 1
) p
CROSS APPLY sys.fn_trace_gettable(pt, DEFAULT)
WHERE EventClass IN (92, 93)
ORDER BY StartTime DESC

AutogrowthDe acuerdo al resultado será la base en la que deberemos trabajar:

  • Si aparece la TEMPDB la opción mas recomendable es: Crear un archivos de Datos (.MDF) y un archivo de LOG( ldf) por cada procesador que tiene el servidor. Y el tamaño inicial total de la base debe ser el actual + 10% . Y luego irlo ajustando a medida que se vaya necesitando.

Verifica el nivel de fragmentación de los indices

El segundo punto importante es verificar que nivel de fragmentación tienen cada uno de los indices que componen la base de datos. Este punto puede provocar que nuestra base de datos tenga un tamaño mayor que el real. Y provoque que las consultas se demoren un poco mas de lo que deberian:

Para corroborarlo podemos usar el siguiente script:

IF OBJECT_ID('tempdb.dbo.#temp') IS NOT NULL
DROP TABLE #temp
GO
CREATE TABLE #temp (
db SYSNAME DEFAULT DB_NAME(),
flname SYSNAME,
size_after_growth DECIMAL(18,2),
size DECIMAL(18,2),
space_used DECIMAL(18,2),
growth INT,
is_percent_growth BIT,
PRIMARY KEY CLUSTERED (db, flname)
)
DECLARE @SQL NVARCHAR(MAX)
SELECT @SQL = STUFF((
SELECT '
USE [' + name + ']
INSERT INTO #temp (flname, size_after_growth, space_used, size, growth, is_percent_growth)
SELECT
name
, CASE WHEN is_percent_growth = 1 THEN size * (1 + (growth / 100.)) ELSE size + growth END * 8. / 1024
, space_used = FILEPROPERTY(name, ''SpaceUsed'') * 8. / 1024
, size = size * 8. / 1024
, CASE WHEN is_percent_growth = 1 THEN growth ELSE growth * 8. / 1024 END
, is_percent_growth
FROM sys.database_files'
FROM sys.databases
WHERE [state] = 0
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, '')
EXEC sys.sp_executesql @SQL
SELECT
db
, flname
, size_after_growth
, size
, space_used
, CAST(growth AS VARCHAR(10)) + CASE WHEN is_percent_growth = 1 THEN ' %' ELSE ' MB' END
FROM #temp
WHERE (is_percent_growth = 0 AND growth < 50)
OR (is_percent_growth = 1 AND growth < 5)
OR (size - space_used < 20)

 

Para correguirlo podemos ejecutar el siguiente script por cada una de nuestras bases de datos:

DECLARE @SQL NVARCHAR(MAX)
SELECT @SQL = (
SELECT '
ALTER INDEX [' + i.name + N'] ON [' + SCHEMA_NAME(o.[schema_id]) + '].[' + o.name + '] ' +
CASE WHEN s.avg_fragmentation_in_percent > 30
THEN 'REBUILD'
ELSE 'REORGANIZE'
END + ';
'
FROM (
SELECT
s.[object_id]
, s.index_id
, avg_fragmentation_in_percent = MAX(s.avg_fragmentation_in_percent)
FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, NULL) s
WHERE s.page_count > 128 -- > 1 MB
AND s.index_id > 0 -- <> HEAP
AND s.avg_fragmentation_in_percent > 5
GROUP BY s.[object_id], s.index_id
) s
JOIN sys.indexes i ON s.[object_id] = i.[object_id] AND s.index_id = i.index_id
JOIN sys.objects o ON o.[object_id] = s.[object_id]
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)')
PRINT @SQL
EXEC sys.sp_executesql @SQL

 

 

Contar días hábiles entre una fecha

Como contar días entre fechas

La siguiente función para SQL Server permite contar la cantidad de días que existen entre un rango de fechas sin contar Sábados y Domingos.

CREATE FUNCTION [dbo].[DiasHabiles](@FechaInicio DATETIME,@FechaFin DATETIME) 
 RETURNS integer 
 AS 
 BEGIN

            DECLARE @DiasNormales INT	--Con esta variable calculamos cuantos dias "normales" hay en el rango de fechas 
            DECLARE @DiasHabiles INT  --Con esta variable acumulamos los dias totales 
            DECLARE @Contador INT		--Esta variable nos sirve de contador para saber cuando lleguemos al ultimo dia del rango 
            DECLARE @Aux_Fecha DATETIME	--Esta variable es la que comparamos para saber si el dia que esta calculando es sábado o domingo*

            /*Esta par de variables sirven para comparar las dos fechas, si son iguales, la funcion nos regresa un 0*/ 
            DECLARE @Aux_FechaInicio VARCHAR(10) 
            DECLARE @Aux_FechaFin VARCHAR(10) 

            --Inicializamos algunas variables 

			SET @DiasNormales = 0 
            SET @DiasHabiles = 0 
            SET @Contador=0 

            --Calculamos cuantos dias normales hay en el rango de fechas  
            SELECT @DiasNormales = DATEDIFF(DAY,@FechaInicio,@FechaFin) + 1 

            /*Ordenamos el formato de las fechas para que no importando como se proporcionen se comparen igual*/ 

            SELECT @Aux_FechaInicio = (SELECT CAST((CAST(datepart(dd,@FechaInicio)AS 
                                   VARCHAR(2))+'/'+ CAST(datepart(mm,@FechaInicio)AS 
                                   VARCHAR(2))+'/'+CAST(datepart(yy,@FechaInicio)AS VARCHAR(4))) as 
                                   varchar(10))) 
            SELECT @Aux_FechaFin = (SELECT CAST((CAST(datepart(dd,@FechaFin)AS 
                                   VARCHAR(2))+'/'+ CAST(datepart(mm,@FechaFin)AS VARCHAR(2))+'/'+ 
                                   CAST(datepart(yy,@FechaFin)AS VARCHAR(4)))as varchar(10))) 


            --Se comparan las dos fechas 

            IF @Aux_FechaInicio <>@Aux_FechaFin 
			BEGIN 
				/*Si la diferencia de fechas es igual a dos, es porque solo ha transcurrido un dia, asi que solo se valida que no vaya a marcar dias de mas*/ 
				IF @DiasNormales = 2 
				BEGIN 
					SELECT @DiasHabiles = 1 
				END 
				ELSE 
				BEGIN 
					WHILE @Contador < @DiasNormales 
					BEGIN 
						/*Se Iguala la fecha a que vamos a calcular para saber si es sabado o domingo en la variable @Aux_Fecha sumandole los dias que marque el contador, el cual no debe ser mayor que el numero total de dias que hay en el rango de fechas*/ 
						SELECT @Aux_Fecha = @FechaInicio + @Contador 
						/*Utilizando la funcion datepart con el parametro dw que calcula que dia de la semana corresponde una fecha determinada, determinados que no sea sabado (7) o domingo (1)*/ 
							IF ((datepart(dw,@Aux_Fecha) <> 1) and (datepart(dw,@Aux_Fecha) <> 7) ) 
							BEGIN
								/*Si no es sabado o domingo, entonces se suma uno al total de dias que queremos desplegar*/ 
								SELECT @DiasHabiles = @DiasHabiles + 1 
							END 
						--Se suma un dia mas al contador 
						SELECT @Contador = @Contador + 1 
					END 
				END 
			END 
            ELSE 
            BEGIN 
            --Si fuese cierto que las fechas eran iguales se despliegue cero 
            SELECT @DiasHabiles = 0 
            END 

            --Al finalizar el ciclo, la funcion regresa el numero total de dias 
            RETURN(@DiasHabiles) 
END

GO

 

Su uso es muy simple:

Select dbo.DiasHabiles('2015/07/13','2015/07/31') as DiasHabiles,DateDiff(d,'2015/07/13','2015/07/31') as DiasCorridos

 

 

Resultado_contar_fechas

En este ejemplo se puede ver la variación que existe entre la función DateDiff y nuestra función.

Averiguar el Puerto del SQL Server

¿Cómo saber en que puerto está corriendo nuestro motor SQL Server? Primero que nada es conveniente entender porque es que no esta en su puerto default. Si eres novato en el tema, seguramente tienes la instalación estándar del motor de Microsoft, y nunca te has preguntado porque debería cambiarlo de puerto. Si es tu caso te dejo este artículo donde te contamos como es la seguridad del MS SQL Server y que cosas debes tener en cuenta. (https://maurobernal.com.ar/blog/consejos-para-asegurar-tu-ms-sql-server/)

Para aquellos que entendemos el porqué debemos cambiarlo, y no sabemos como hacerlo, te dejo este otro artículo. (https://maurobernal.com.ar/blog/mssql/cambiar-el-puerto-del-ms-sql-server)

Y para aquellos que sabemos lo anterior, pero por diferentes motivos nos toca implementar una aplicación, y no sabemos en que puerto está corriendo, a continuación te damos una idea de como averiguarlo.

Averiguar el Puerto en el que está funcionando el SQL Server:

Por defecto el motor SQL Server trabaja en los siguientes puertos de manera predeterminada:

  • TCP:1433
  • UDP:1433

Pero puede ocurrir que esto al tener varias instancias, o por otros motivos que no vienen al caso, no sean los puertos en los que está funcionando nuestro Motor. Para averiguar el puerto podemos utilizar los siguientes 3 métodos:

  1. Registros de errores de lectura de SQL Server
  2. Usando el Administrador de configuración de SQL Server (SQL Server Configuration Manager )
  3. Usando el visor de sucesos (o Eventos) de Windows (Windows Application Event Viewer)

1-Registros de errores de lectura de SQL Server:

USE master
GO
xp_readerrorlog 0, 1, N'Server is listening on' 
GO

port_number

Los parámetros que puede utilizar con XP_READERRRORLOG se mencionan a continuación para su referencia:

  1.  1. Valor de los archivos de registro de errores que quieran leer: 0 = actual, 1 = Archivo # 1, 2 = Archivo # 2, etc …
  2. Tipo de archivo: 1 o NULL = log de ​​errores, 2= registro de Agente SQL 
  3. Cadena de búsqueda 1: Primer cadena de texto que se quiere buscar
  4. Cadena de búsqueda 2: Segunda cadena de texto a buscar
  5. Fecha de Inicio para la búsqueda
  6. Fecha Fin para la búsqueda
  7. Orden de los Resultados : N’asc’ = Ascendente, N’desc’ = Descendiente

2-Usando el Administrador de Configuración del SQL Server:

Se debe ir a INICIO \ Todos los Programas \ Microsoft SQL Server 200X \ Configuration Tools \ SQL Server Configuration Manager

configuration_manager_port

 3-Usando el Visor de Eventos de Windows:

Se deben filtrar los eventos cuyo ID es 26022

visor_port_sql

visor_port_sql_number

Video Explicando todo este proceso

Contar días sin Sábado ni Domingo

Como contar cuántos días hay en un período sin contar sábados y domingo

La siguiente es una  función en TSQL de MS SQL Server, la cúal permite saber la cantidad de días que existe en un período determinado sin contar los fines de semana (sábado y domingo).

--Primeramente declaramos que vamos a crear una funcion, en este caso se llama Dif Dias y recibe dos parámetros, la fecha inicial del período y la final*/ 
CREATE FUNCTION [dbo].[DifDias](@StartDate DATETIME,@EndDate DATETIME) 
 RETURNS integer 
 AS 
 Begin 

		DECLARE @DaysBetween INT  --Con esta variable calculamos cuantos dias "normales" hay en el rango de fechas 
		DECLARE @BusinessDays INT  --Con esta variable acumulamos los dias totales 
		DECLARE @Cnt INT --esta variable nos sirve de contador para saber cuando lleguemos al ultimo dia del rango 
		DECLARE @EvalDate DATETIME   --esta variable es la que comparamos para saber si el dia que esta calculando es sábado o domingo*

		/*Esta par de variables sirven para comparar las dos fechas, si son iguales, la funcion nos regresa un 0*/ 
		DECLARE @ini VARCHAR(10) 
		DECLARE @fin VARCHAR(10) 

		--Inicializamos algunas variables 

		 SET @DaysBetween = 0 
		 SET @BusinessDays = 0 
		 SET @Cnt=0 

		--Calculamos cuantos dias normales hay en el rango de fechas  
		SELECT @DaysBetween = DATEDIFF(DAY,@StartDate,@EndDate) + 1 

		/*Ordenamos el formato de las fechas para que no importando como se proporcionen se comparen igual*/ 

		SELECT @ini = (SELECT CAST((CAST(datepart(dd,@StartDate)AS 
						VARCHAR(2))+'/'+ CAST(datepart(mm,@StartDate)AS 
						VARCHAR(2))+'/'+CAST(datepart(yy,@StartDate)AS VARCHAR(4))) as 
						varchar(10))) 
		SELECT @fin = (SELECT CAST((CAST(datepart(dd,@EndDate)AS 
						VARCHAR(2))+'/'+ CAST(datepart(mm,@EndDate)AS VARCHAR(2))+'/'+ 
						CAST(datepart(yy,@EndDate)AS VARCHAR(4)))as varchar(10))) 


		--Se comparan las dos fechas 

		IF @ini <>@fin 
		 BEGIN 

		/*Si la diferencia de fechas es igual a dos, es porque solo ha transcurrido un dia, asi que solo se valida que no vaya a marcar dias de mas*/ 

		IF @DaysBetween = 2 
		 BEGIN 
		 SELECT @BusinessDays = 1 
		 END 
		 ELSE 
		 BEGIN 
		 WHILE @Cnt < @DaysBetween 
		 BEGIN 

		/*Se Iguala la fecha a que vamos a calcular para saber si es sabado o domingo en la variable @EvalDate sumandole los dias que marque el contador, el cual no debe ser mayor que el numero total de dias que hay en el rango de fechas*/ 

		SELECT @EvalDate = @StartDate + @Cnt 

		/*Utilizando la funcion datepart con el parametro dw que calcula que dia de la semana corresponde una fecha determinada, determinados que no sea sabado (7) o domingo (1)*/ 

		IF ((datepart(dw,@EvalDate) <> 1) and 
		 (datepart(dw,@EvalDate) <> 7) ) 
		 BEGIN 

		/*Si no es sabado o domingo, entonces se suma uno al total de dias que queremos desplegar*/ 

		SELECT @BusinessDays = @BusinessDays + 1 
		 END 

		--Se suma un dia mas al contador 

		SELECT @Cnt = @Cnt + 1 
		 END 
		 END 
		 END 
		 ELSE 
		 BEGIN 

		--Si fuese cierto que las fechas eran iguales se despliegue cero 

		SELECT @BusinessDays = 0 
		 END 
		 
		 
		 
		--Al finalizar el ciclo, la funcion regresa el numero total de dias 

		return (@BusinessDays) 
		 END

GO

Ejemplo de Uso:

SELECT  dbo.DifDias('06/01/2015', '06/30/2015')  as DiasAbril

contar dias-sin-sabado-ni-domingo

Truncar Fecha en SQL Server

Porque trabajas todo el día con un motor MS SQL Server, y te toca cambiar los formatos de visualización de las fechas, aquí te dejo una ayuda memoria:

De la siguiente manera es posible quitar las horas y los segundos a una fecha.

select getdate()

-- La manera correcta (desde SQL Server 2008)
select cast(getdate() As Date)

-- La manera correcta(anterior a SQL Server 2008)
select dateadd(dd, datediff(dd,0, getDate()), 0)

truncar-fecha

Reparar una base dañada de MS SQL Server

Últimamente me ha tocado quemarme las pestañas por casos de bases de datos dañadas. Una mala infraestructura, y/o un mal plan de backups termina provocando este tipo de post luego de sufrir por un rato…

Reparar una base dañada

El siguiente es un error común cuando se daña una base:

Msg 824, Level 24, State 2, Line 11
SQL Server detected a logical consistency-based I/O error: incorrect pageid (expected 1:49876; actual 17253:-991032068). It occurred during a read of page (1:49876) in database ID 15 at offset 0x000000185a8000 in file ‘E:\Bases\SBDAXXXX.MDF’.  Additional messages in the SQL Server error log or system event log may provide more detail. This is a severe error condition that threatens database integrity and must be corrected immediately. Complete a full database consistency check (DBCC CHECKDB). This error can be caused by many factors; for more information, see SQL Server Books Online.

A continuación los pasos que se debería seguir:

  1. Intentar hacer un backup de la base
  2. Obtener la cantidad de registros que hay en ese momento en cada tabla (script adjunto al final)
  3. Colocar la base en modo de usuario único
    ALTER DATABASE SBDAXXXX SET SINGLE_USER WITH ROLLBACK IMMEDIATE

     

  4. Intentar reparar la base
    DBCC CHECKDB(SBDAXXXX,REPAIR_ALLOW_DATA_LOSS)

     

  5. Verificar la cantidad de registros actual (script adjunto al final)
DECLARE @Tabla VARCHAR(250)
DECLARE @SQL VARCHAR(2000)
CREATE TABLE #TablaTemp(ID INT IDENTITY(1,1),Tabla_Nombre VARCHAR(200),Cant_Registros INT)

DECLARE TINFO_CUR CURSOR FOR 
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_TYPE='BASE TABLE'

OPEN TINFO_CUR
FETCH NEXT FROM TINFO_CUR INTO @Tabla
WHILE @@FETCH_STATUS =0
BEGIN
SET @SQL='INSERT INTO #TablaTemp(Tabla_Nombre,Cant_Registros) SELECT '''+@Tabla+''',COUNT(*) FROM '+@Tabla+''
EXECUTE (@SQL)
FETCH NEXT FROM TINFO_CUR INTO @Tabla
END
CLOSE TINFO_CUR
DEALLOCATE TINFO_CUR


SELECT * FROM #TablaTemp ORDER BY Tabla_Nombre

DROP TABLE #TablaTemp

 

Si la base está muy dañada posiblemente no se repara, o se pierde información. En ese caso se puede recurrir a un software de 3ro para intentar reparar el .MDF.

Listar Triggers

Como identificar las triggers que hay en tu base de datos

Siempre es útil poder listar las triggers que tienes funcionando en tu server de producción.

Para ellos es que surge el siguente script:

SELECT O.name AS [Trigger]
,OBJECT_NAME(parent_obj) AS Tabla
,OBJECTPROPERTY( id,'ExecIsUpdateTrigger') AS Es_Update
,OBJECTPROPERTY( id,'ExecIsDeleteTrigger') AS Es_Delete
,OBJECTPROPERTY( id,'ExecIsInsertTrigger') AS Es_Insert
,OBJECTPROPERTY( id,'ExecIsAfterTrigger') AS Es_After
,OBJECTPROPERTY( id,'ExecIsInsteadOfTrigger') AS Es_insteadof
 ,OBJECTPROPERTY(id, 'ExecIsTriggerDisabled') AS Habilitado
FROM sysobjects O INNER JOIN sysusers U ON O.uid = U.uid
INNER JOIN sys.tables T ON O.parent_obj = T.object_id
INNER JOIN sys.schemas S ON T.schema_id = S.schema_id
WHERE O.type = 'TR'

 

Resultado en un Microsoft SQL Server 2008 R2 x64 con el Microsoft SQL Server Management Studio:

Listar Triggers con TSQL

Directorio de Backup de MS SQL predeterminado

Restaurar backup es un proceso, que en algunos casos se debe desarrollar diariamente. Por ello es bueno optimizar los tiempos.

A continuación un Tips para que al buscar el backup con el Microsoft
SQL Server Management Studio les abra en un directorio que ustedes elijan.

En este caso estoy trabajando con SQL Server 2008 R2 x64 Enterprise. Al intentar levantar un backup siempre abre el “examinar” en el mismo lugar:
“C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\Backup”

 

Para modificar dicha ruta predeterminada realizamos lo siguiente:

  1. Ingresamos al Editor del Registro de Windows (regedit)
  2. Navegamos dentro del registro por MIPC\HKLM\Software\Microsoft\Microsoft Sql Server\(Motor + Instancia)\MSSQLServer:
  3. Buscamos y modificamos la clave “BackupDirectory” por el directorio que nosotros queramos:

 

Listo! Ahora la próxima vez que intentemos recuperar un backup, abrirá directamente en dicha carpeta:

Mejorar rendimiento de SQL Server – Estadísticas de Espera

En este oficio se escucha de manera repetitiva frases como: “Mi servidor anda lento“, “Se tarda demasiado“, “como hago para que funcione más rápido“.

Al intentar encontrar la causa del problema muchas veces no sabes dónde empezar. En esta serie de artículos veremos algunos pasos a seguir para tratar de determinar el motivo que lo origina.
A tener en cuenta:

Generalmente el resultado es ocasionado, no solo por un motivo, sino por la suma de varios. Por lo se debe analizar y tomar resultados de la mayor cantidad de variables posibles (red, disco, memoria, consultas, etc) y recién ahí, en conjunto tomar medidas. Caso contrario, si se analizan por separado, seguramente cada uno determinará una solución diferente.

 

Estádisticas de Espera (waits statistics)
Nos darán una visión general de cuáles son los mayores tiempos de espera a nivel de recursos y de sistema operativo.
En esta oportunidad nos valemos de un script de http://habrahabr.ru/post/216309/ para listar los mismos:

SELECT TOP 10 
wait_type , max_wait_time_ms wait_time_ms , signal_wait_time_ms , wait_time_ms - signal_wait_time_ms AS resource_wait_time_ms , 
100.0 * wait_time_ms / SUM(wait_time_ms) OVER ( ) AS percent_total_waits , 100.0 * signal_wait_time_ms / 
SUM(signal_wait_time_ms) OVER ( ) AS percent_total_signal_waits , 100.0 * ( wait_time_ms - signal_wait_time_ms ) / 
SUM(wait_time_ms) OVER ( ) AS percent_total_resource_waits FROM sys.dm_os_wait_stats WHERE wait_time_ms > 0 
-- remove zero wait_time 
AND wait_type NOT  IN 
 -- filter out additional irrelevant waits
(	'SLEEP_TASK', 'BROKER_TASK_STOP', 'BROKER_TO_FLUSH', 'SQLTRACE_BUFFER_FLUSH','CLR_AUTO_EVENT', 'CLR_MANUAL_EVENT', 
	'LAZYWRITER_SLEEP', 'SLEEP_SYSTEMTASK', 'SLEEP_BPOOL_FLUSH', 'BROKER_EVENTHANDLER', 'XE_DISPATCHER_WAIT', 'FT_IFTSHC_MUTEX',
	'CHECKPOINT_QUEUE', 'FT_IFTS_SCHEDULER_IDLE_WAIT', 'BROKER_TRANSMITTER', 'FT_IFTSHC_MUTEX', 'KSOURCE_WAKEUP', 'LAZYWRITER_SLEEP', 
	'LOGMGR_QUEUE', 'ONDEMAND_TASK_QUEUE', 'REQUEST_FOR_DEADLOCK_SEARCH', 'XE_TIMER_EVENT', 'BAD_PAGE_PROCESS', 'DBMIRROR_EVENTS_QUEUE',
	'BROKER_RECEIVE_WAITFOR', 'PREEMPTIVE_OS_GETPROCADDRESS', 'PREEMPTIVE_OS_AUTHENTICATIONOPS', 'WAITFOR', 'DISPATCHER_QUEUE_SEMAPHORE', 
	'XE_DISPATCHER_JOIN', 'RESOURCE_QUEUE' ) 
ORDER  BY wait_time_ms DESC

 


 

El resultado dependerá de su servidor:
A continuación una descripción de los waits mas comunes:

  • CXPACKET o A menudo indica nada más que ciertas consultas se ejecutan con el paralelismo; CXPACKET no son una señal inmediata de los problemas, a pesar de que puede ser el síntoma de otro problema, asociado con uno de los otros tipos de espera alto valor en la instancia.
  • SOS_SCHEDULER_YIELD o Las tareas que se ejecutan en el sistema pueden haber superado su cantidad permitida, y están teniendo que esperar en la cola de ejecutables. Esto puede indicar que el servidor está bajo demasiada presión.
  • ThreadPool o Una tarea tuvo que esperar a tener un trabajador libre para poder ejecutarla. Esta podría ser una señal de inanición de subproceso de trabajo, lo que requiere un aumento en el número de CPU en el servidor, para manejar una carga de trabajo altamente concurrente, o puede ser una señal de bloqueo, lo que resulta en un gran número de tareas paralelas que consumen los subprocesos de trabajo por largos períodos.
  • LCK_ * o Estos esperan tipos significan que el bloqueo se produce en el sistema y que las sesiones han tenido que esperar para adquirir un bloqueo de un tipo específico, que fue detenido por otra sesión de base de datos. Este problema puede investigarse más a fondo utilizando, por ejemplo, la información de los sys.dm_db_index_operational_stats.
  • PAGEIOLATCH_ *, IO_COMPLETION, WriteLog o Estas esperas son comúnmente asociados con el disco I / O y ocasionan los cuellos de botella, aunque la causa raíz del problema puede ser, y es comúnmente, una consulta de bajo rendimiento que está consumiendo cantidades excesivas de memoria en el servidor.
  • PAGEIOLATCH_ * se asocian específicamente con los retrasos en la capacidad de leer o escribir datos desde los archivos de base de datos.
  • WriteLog están relacionados con problemas con la escritura en archivos de registro. Estas esperas deben evaluarse conjuntamente con las estadísticas de archivos virtuales, así como los contadores de rendimiento de disco físico, para determinar si el problema es específico de una sola base de datos, archivo o disco, o es ejemplo de ancho.
  • PAGELATCH_ * o Non-I / O espera pestillos de páginas de datos en el grupo de búferes. Muchas veces PAGELATCH_ * esperas están asociados con problemas de contención de la asignación. Uno de los temas más conocidos de las asignaciones asociadas a PAGELATCH_ * espera que ocurra en tempdb cuando se crea y se destruye en el tempdb un gran número de objetos y el sistema experimenta la contención en el Mapa Global Shared Asignación (SGAM), mapa de asignación global (GAM ), y Página espacio libre (PFS) páginas en la base de datos tempdb.
  • LATCH_ * o Estas esperas se asocian con objetos de peso ligero a corto plazo de sincronización que se utilizan para proteger el acceso a las memorias caché internas, pero no el caché del búfer. Estas esperas pueden indicar una serie de problemas, dependiendo del tipo pestillo. La determinación de la clase de enganche específica que tiene el tiempo de espera más acumulado asociado a él se puede encontrar mediante la consulta de los sys.dm_os_latch_stats del DMV.
  • ASYNC_NETWORK_IO o Esta espera es a menudo erróneamente atribuido a un cuello de botella de la red. De hecho, la causa más común de esta espera es que una aplicación cliente está realizando el procesamiento de los datos fila por fila (tipo cursor). Y si bien están siendo transmitidos desde SQL Server como un conjunto de resultados el cliente los procesa fila por fila. La corrección de este tipo de espera generalmente requiere cambiar el código del lado del cliente para que se lea el conjunto de resultados lo más rápido posible, y luego se realiza el procesamiento por el lado del cliente.

 Una vez hecho algún cambio deberé reiniciar los contadodes, y empezar a recopilar las estadísticas de nuevo, para verificar si hubo alguna mejora:

DBCC SQLPERF('sys.dm_os_wait_stats',clear)

Esta primer entrada es el primer paso para determinar obtener una visión generar. En próximas entradas veremos algunas tareas específicas para continuar con la mejora del rendimiento del motor SQL Server.

Averiguar la intercalación de una base de datos

De la siguiente manera podrán averiguar la intercalación (collation) de una base de datos en MS SQL Server:

TSQL:
SELECT
DATABASEPROPERTYEX(‘MASTER’, ‘Collation’)
as Intercalacion;

SQL Server Management Studio: