Cuando fue la ultima que se uso una tabla?

Hace rato que no escribia, he andado como siempre en mucha cosa. Estoy jugando un poco con PostGreSQL y Azure, seguramente empezare a incluir esa informacion en futuras entradas a este blog.

La respuesta  a la pregunta del titulo me ha servido muchas veces como administrador de una base de datos a lo largo de los años.

Esta consulta esta basada en una vista de systema que analiza el uso de los indices de nuestras tablas.

sys.dm_db_index_usage_stats

SELECT  groupname = @groupname, casinoname = @casinoname, DB_NAME(a.database_id) Database_Name ,
        b.name Table_Name ,
        MAX(ISNULL(last_user_update,'2001-01-01')) last_user_update ,
        MAX(ISNULL(last_user_seek,'2001-01-01')) last_user_seek ,
        MAX(ISNULL(last_user_scan,'2001-01-01')) last_user_scan ,
        MAX(ISNULL(last_user_lookup,'2001-01-01')) last_user_lookup
FROM    sys.dm_db_index_usage_stats a
        INNER JOIN sys.tables b ON b.object_id = a.object_id
		INNER JOIN sys.indexes c ON c.object_id = a.object_id
                                    AND c.index_id = a.index_id
WHERE b.name = 'playerbalances'
GROUP BY a.database_id ,
        b.name
ORDER BY a.database_id ,
        b.name ;<span 				data-mce-type="bookmark" 				id="mce_SELREST_start" 				data-mce-style="overflow:hidden;line-height:0" 				style="overflow:hidden;line-height:0" 			></span>

Utilizando este mismo codigo podemos determinar cuando fue la ultima vez que se utilizo uno de nuestros indices

SELECT  DB_NAME(a.database_id) Database_Name ,
        b.name Table_Name ,
        c.name Index_Name ,
        MAX(ISNULL(last_user_update,'2001-01-01')) last_user_update ,
        MAX(ISNULL(last_user_seek,'2001-01-01')) last_user_seek ,
        MAX(ISNULL(last_user_scan,'2001-01-01')) last_user_scan ,
        MAX(ISNULL(last_user_lookup,'2001-01-01')) last_user_lookup
FROM    sys.dm_db_index_usage_stats a
        INNER JOIN sys.tables b ON b.object_id = a.object_id
        INNER JOIN sys.indexes c ON c.object_id = a.object_id
                                    AND c.index_id = a.index_id
WHERE   a.database_id = DB_ID()
GROUP BY a.database_id ,
        b.name ,
        c.name
ORDER BY a.database_id ,
        b.name ,
        c.name;

Toda pieza de informacion es valiosa, en este caso puede ayudarme a ver si mi politica de creacion de indices esta sirviendo o no, puede indicarme cuales tablas tienen mas trafico y ayudarme a tomar decisiones para mejorar un problema de contencion.

Saludos

Referencia:
https://docs.microsoft.com/en-us/sql/relational-databases/system-dynamic-management-views/sys-dm-db-index-usage-stats-transact-sql

Encontrar las dependencias en mi base de datos

Escribe esta consulta temprano para buscar las dependencias de un procedimiento que estaba modificando, pude haber utilizado el sp_depends para que me liste todas las dependencias pero no me hubiese listado los totales que es lo que realmente estaba buscando.

SELECT DISTINCT
OBJECT_NAME(o.object_id) ,
v.name ,
COUNT(1)
FROM
sys.objects o
INNER JOIN master.dbo.spt_values v ON o.type = SUBSTRING(v.name, 1, 2) COLLATE catalog_default
AND v.type = 'O9T'
INNER JOIN sys.sql_dependencies d ON o.object_id = d.object_id
INNER JOIN sys.schemas s ON o.schema_id = s.schema_id
WHERE
o.object_id = OBJECT_ID('<MIPROCEDIMIENTO>')
AND d.class < 2
GROUP BY
OBJECT_NAME(o.object_id) ,
v.name
ORDER BY
3 DESC;
GO


sp_depends '<MIPROCEDIMIENTO>';</pre>
<pre>

sp_executesql vrs sp_sqlexec

Estos procedimientos son utilizados comúnmente para ejecutar codigo Transact de manera dinamica; es codigo que armamos a partir de hileras para producir un producto que de otra forma seria un poco complicado.

sp_sqlexec esta en desuso, es un procedimiento que MSSQL ya no soporta y por tanto se deberia de reescribir cualquier codigo que lo este utilizando en este momento.

Cuando ejecutamos codigo dinamico podemos usar sp_executesql o bien exec. Con la diferencia de que el sp_executesql probablemente creara un plan de ejecucion que se pueda reutilizar para ejecuciones posteriores.

Sintaxis


USE master
GO

DECLARE @vsql NVARCHAR(max)

SET @vsql = 'select top 210 * from sys.tables'

EXEC(@vsql)

EXEC sys.sp_sqlexec @vsql

EXEC sys.sp_executesql @vsql