Si te interesa esta información, descargatela GRATIS
Descargar PDF Gratis¿Sabes cuántos gigabytes está consumiendo realmente cada base de datos y cada tabla de tu gestor SQL Server? Es una pregunta sencilla que muchos administradores de sistemas y DBAs pasan por alto... hasta que el almacenamiento empieza a llenarse sin una razón clara. No es magia negra: es gestión de espacio. Y cuando se trata de optimizar rendimiento, costos y evitar disgustos con el área de infraestructura, conocer el consumo real de espacio a nivel de bases de datos y tablas es tan vital como hacer un buen backup.
SQL Server no solo almacena datos: almacena índices, estadísticas, objetos temporales y estructuras internas que también ocupan espacio. Pero no siempre están visibles a simple vista. Por eso, no basta con mirar el tamaño total de la base de datos desde el Management Studio: hay que indagar más, con consultas específicas, bien afinadas, que te revelen la realidad de tu sistema. Esa realidad que se traduce en gigas, IOPS y posibles cuellos de botella.
En este artículo vas a encontrar un set de consultas prácticas, explicadas paso a paso, que te permitirán obtener métricas precisas sobre el espacio utilizado en SQL Server. Desde cuánto ocupa cada tabla o índice, hasta cómo detectar espacio reservado pero no utilizado. Ideal si estás planificando migraciones, haciendo auditorías de rendimiento, o simplemente necesitas tener control total sobre el crecimiento de tus datos. Prepárate para ver SQL Server con otros ojos.
Espacio ocupado por cada Base de Datos
SELECT 0 as id, CONVERT (date, GETDATE()) date, d.name, a.name as filename,
a.physical_name as location,(a.size/128)as sizeMB
FROM sys.master_files a INNER JOIN sys.databases d ON (a.database_id = d.database_id)
ORDER BY sizeMB DESC
Filas de cada una de las tabla de una Base de Datos
SELECT SCHEMA_NAME(schema_id) AS [SchemaName], [Tables].name AS [TableName],
SUM([Partitions].[rows]) AS [TotalRowCount]
FROM sys.tables AS [Tables]
JOIN sys.partitions AS [Partitions]
ON [Tables].[object_id] = [Partitions].[object_id]
AND [Partitions].index_id IN ( 0, 1 )
GROUP BY SCHEMA_NAME(schema_id), [Tables].name
ORDER BY TotalRowCount DESC
Defragmentar Índices de una Base de Datos
WITH INDICES (BD, INDICETIPO, FRAGMENTACION, INDICE, TABLA) AS ( SELECT DBS.NAME BASEDEDATOS, PS.INDEX_TYPE_DESC, PS.AVG_FRAGMENTATION_IN_PERCENT, IND.NAME INDICE, TAB.NAME TABLA FROM SYS.DM_DB_INDEX_PHYSICAL_STATS (DB_ID(), NULL, NULL, NULL, NULL) PS INNER JOIN SYS.DATABASES DBS ON PS.DATABASE_ID = DBS.DATABASE_ID INNER JOIN SYS.INDEXES IND ON PS.OBJECT_ID = IND.OBJECT_ID INNER JOIN SYS.TABLES TAB ON TAB.OBJECT_ID = IND.OBJECT_ID WHERE IND.NAME IS NOT NULL AND PS.INDEX_ID = IND.INDEX_ID AND PS.AVG_FRAGMENTATION_IN_PERCENT > 0) SELECT DISTINCT CASE WHEN FRAGMENTACION > 5 AND FRAGMENTACION <= 30 THEN 'ALTER INDEX ' + INDICE + ' ON ' + TABLA + ' REORGANIZE' WHEN FRAGMENTACION > 30 THEN 'ALTER INDEX ' + INDICE + ' ON ' + TABLA + ' REBUILD' END QUERY, FRAGMENTACION, BD, INDICE, TABLA FROM (SELECT FRAGMENTACION, INDICE, TABLA, BD FROM INDICES WHERE FRAGMENTACION > 5) A ORDER BY FRAGMENTACION DESC
Espacio a Liberar de todas las Bases de Datos (Skink)
SELECT d.name AS DatabaseName, mf.name AS LogicalFileName, CASE mf.type WHEN 0 THEN 'DATA' WHEN 1 THEN 'LOG' END AS FileType, CAST(mf.size * 8.0 / 1024 AS DECIMAL(10,2)) AS SizeMB, CAST(FILEPROPERTY(mf.name, 'SpaceUsed') * 8.0 / 1024 AS DECIMAL(10,2)) AS UsedSpaceMB, CAST((mf.size - FILEPROPERTY(mf.name, 'SpaceUsed')) * 8.0 / 1024 AS DECIMAL(10,2)) AS FreeSpaceMB, CAST(((mf.size - FILEPROPERTY(mf.name, 'SpaceUsed')) * 100.0 / mf.size) AS DECIMAL(5,2)) AS FreeSpacePercent, CASE WHEN CAST(((mf.size - FILEPROPERTY(mf.name, 'SpaceUsed')) * 100.0 / mf.size) AS DECIMAL(5,2)) > 25 THEN 'Alto potencial' WHEN CAST(((mf.size - FILEPROPERTY(mf.name, 'SpaceUsed')) * 100.0 / mf.size) AS DECIMAL(5,2)) > 10 THEN 'Moderado potencial' WHEN CAST(((mf.size - FILEPROPERTY(mf.name, 'SpaceUsed')) * 100.0 / mf.size) AS DECIMAL(5,2)) > 5 THEN 'Bajo potencial' ELSE 'No recomendado' END AS ShrinkRecommendation FROM sys.databases d INNER JOIN sys.master_files mf ON d.database_id = mf.database_id WHERE d.state = 0 -- Solo bases de datos ONLINE AND d.name NOT IN ('master', 'model', 'msdb', 'tempdb') -- Excluir bases de sistema AND mf.type IN (0, 1) -- Solo archivos de datos y log AND HAS_DBACCESS(d.name) = 1 -- Solo bases accesibles ORDER BY FreeSpacePercent DESC, d.name, mf.type;
Espacio Ocupado por las Tablas Más Grandes en una Base de Datos
SELECT t.name AS TableName, s.name AS SchemaName, p.rows AS RowCounts,
SUM(a.total_pages) * 8 AS TotalSpaceKB, CAST(ROUND(((SUM(a.total_pages) * 8) / 1024.00), 2) AS NUMERIC(36, 2)) AS TotalSpaceMB, SUM(a.used_pages) * 8 AS UsedSpaceKB,
CAST(ROUND(((SUM(a.used_pages) * 8) / 1024.00), 2) AS NUMERIC(36, 2)) AS UsedSpaceMB, (SUM(a.total_pages) - SUM(a.used_pages)) * 8 AS UnusedSpaceKB, CAST(ROUND(((SUM(a.total_pages) - SUM(a.used_pages)) * 8) / 1024.00, 2) AS NUMERIC(36, 2)) AS UnusedSpaceMB FROM sys.tables t INNER JOIN sys.indexes i ON t.object_id = i.object_id INNER JOIN sys.partitions p ON i.object_id = p.object_id AND i.index_id = p.index_id INNER JOIN sys.allocation_units a ON p.partition_id = a.container_id LEFT OUTER JOIN sys.schemas s ON t.schema_id = s.schema_id WHERE t.is_ms_shipped = 0 AND i.object_id > 255 GROUP BY t.name, s.name, p.rows ORDER BY TotalSpaceMB DESC