2008-11-25 48 views
70

¿Podemos tener una consulta SQL que básicamente ayudará a ver los tamaños de tabla y de índice en SQl Server.Tamaño de tabla e índice en SQL Server

¿Cómo SQL Server mantiene el uso de memoria para tablas/índices?

+0

Ya existen respuestas a esta, pero yo personalmente uso la consulta en este enlace: http: // qualityofdata. com/2011/02/02/analise-table-space-usage-in-sql-server/ – naiem

+0

También puede encontrar el procedimiento almacenado 'sp_helpdb' útil –

Respuesta

65

El parámetro exec sp_spaceused sin parámetro muestra el resumen de toda la base de datos. La solución foreachtable genera un conjunto de resultados por tabla, que SSMS podría no ser capaz de manejar si tiene demasiadas tablas.

Creé un script que recopila las informaciones de la tabla a través de sp_spaceused y muestra un resumen en un solo conjunto de registros, ordenados por tamaño.

create table #t 
(
    name nvarchar(128), 
    rows varchar(50), 
    reserved varchar(50), 
    data varchar(50), 
    index_size varchar(50), 
    unused varchar(50) 
) 

declare @id nvarchar(128) 
declare c cursor for 
select '[' + sc.name + '].[' + s.name + ']' FROM sysobjects s INNER JOIN sys.schemas sc ON s.uid = sc.schema_id where s.xtype='U' 

open c 
fetch c into @id 

while @@fetch_status = 0 begin 

    insert into #t 
    exec sp_spaceused @id 

    fetch c into @id 
end 

close c 
deallocate c 

select * from #t 
order by convert(int, substring(data, 1, len(data)-3)) desc 

drop table #t 
+4

Su secuencia de comandos solo maneja tablas en el esquema 'dbo'. Si tengo una tabla en mi base de datos con un esquema de 'Auditoría', sp_spaceused debe llamarse así: exec sp_spaceused 'Audit.Data'.Por lo tanto, la secuencia de comandos debe modificarse para incluir el nombre de la tabla precedido por el nombre del esquema (separado por un punto) para que devuelva datos sobre las tablas de otros esquemas. – Baodad

+1

Buen punto @Boadad ... que debería ser una solución súper fácil. Sustitución de la "seleccione el nombre desde donde sysobjects xtype = 'U'" con esto debe hacer el truco: "seleccione '[' + sc.name + ']. [' + S.name + ']' FROM sysobjects s ​​ INNER JOIN sys.schemas sc ON s.uid = sc.schema_id donde s.xtype = 'U' " ¡Excelente script, gracias! – DCaugs

+0

en lugar de usar una tabla temporal ¿podemos insertar datos en otra tabla que no sea temporal? – ldevp

13
EXEC sp_MSforeachtable @command1="EXEC sp_spaceused '?'" 
+2

Si publica código, XML o muestras de datos, ** POR FAVOR ** resalte esas líneas en el editor de texto y haga clic en el botón "muestras de código" ('{}') en la barra de herramientas del editor para formatear y sintaxis y ¡resaltarlo! –

0

Hay un procedimiento almacenado extendido sp_spaceused que obtiene esta información. Es bastante intrincado hacerlo desde el diccionario de datos, pero This link se expande a un script que lo hace. This stackoverflow question tiene un poco de información detallada sobre las estructuras de datos subyacentes que puede usar para construir estimaciones de tamaños de tabla e índice para la planificación de capcity.

107

sp_spaceused le da el tamaño de todos los índices combinados.

Si desea que el tamaño de cada índice para una tabla, utilice una de estas dos consultas:

SELECT 
    i.name     AS IndexName, 
    SUM(s.used_page_count) * 8 AS IndexSizeKB 
FROM sys.dm_db_partition_stats AS s 
JOIN sys.indexes    AS i 
ON s.[object_id] = i.[object_id] AND s.index_id = i.index_id 
WHERE s.[object_id] = object_id('dbo.TableName') 
GROUP BY i.name 
ORDER BY i.name 

SELECT 
    i.name    AS IndexName, 
    SUM(page_count * 8) AS IndexSizeKB 
FROM sys.dm_db_index_physical_stats(
    db_id(), object_id('dbo.TableName'), NULL, NULL, 'DETAILED') AS s 
JOIN sys.indexes AS i 
ON s.[object_id] = i.[object_id] AND s.index_id = i.index_id 
GROUP BY i.name 
ORDER BY i.name 

Los resultados son por lo general ligeramente diferente, pero dentro del 1%.

+0

La primera consulta incluye claves principales, lo cual es un poco confuso por un par de razones. – quillbreaker

+0

La segunda consulta arroja 'Msg 102, Nivel 15, Estado 1, Línea 5 - Sintaxis incorrecta cerca de '(' .' en mí, pero no puedo ver ningún problema con la sintaxis. ¿Alguna idea? – Oliver

+0

Oliver, ¿qué versión es ¿Estás corriendo? Funciona como está para mí en 2008R2 y 2012. –

15

En SQL 2012 conseguir esta información en un nivel de la mesa se ha convertido deliciosamente simple:

SQL Management Studio -> clic derecho sobre db -> Informes -> Informes estándar -> Uso del disco junto a la mesa!

Disfrute

3

He aquí la versión más compacta de la respuesta de mayor éxito:

create table #tbl(
    name nvarchar(128), 
    rows varchar(50), 
    reserved varchar(50), 
    data varchar(50), 
    index_size varchar(50), 
    unused varchar(50) 
) 

exec sp_msforeachtable 'insert into #tbl exec sp_spaceused [?]' 

select * from #tbl 
    order by convert(int, substring(data, 1, len(data)-3)) desc 

drop table #tbl 
3

es ser un largo tiempo desde la creación de este puesto, pero quería compartir mi guión:

WITH CteIndex 
AS 
(
SELECT 
    reservedpages = (reserved_page_count) 
    ,usedpages = (used_page_count) 
    ,pages = (
      CASE 
       WHEN (s.index_id < 2) THEN (in_row_data_page_count + lob_used_page_count + row_overflow_used_page_count) 
       ELSE lob_used_page_count + row_overflow_used_page_count 
      END 
      )  
    ,s.object_id 
    ,i.index_id   
    ,i.type_desc AS IndexType 
    ,i.name AS indexname 
    FROM sys.dm_db_partition_stats s 
    INNER JOIN sys.indexes i ON s.[object_id] = i.[object_id] AND s.index_id = i.index_id 
) 
SELECT DISTINCT 
DB_NAME(DB_ID()) AS DatabaseName 
,o.name AS TableName 
,o.object_id 
,ct.indexname 
,ct.IndexType 
,ct.index_id 
, IndexSpace = LTRIM (STR ((CASE WHEN usedpages > pages THEN CASE WHEN ct.index_id < 2 THEN pages ELSE (usedpages - pages) END ELSE 0 END) * 8, 15, 0) + ' KB') 
FROM CteIndex ct 
INNER JOIN sys.objects o ON o.object_id = ct.object_id 
INNER JOIN sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL, NULL , NULL) ps ON ps.object_id = o.object_id 
AND ps.index_id = ct.index_id 
ORDER BY name ASC 

funciona para:

  • SQL Server (a partir de 2008)
  • Incluye información para todas las tablas por base de datos actual
2
--Gets the size of each index for the specified table 
DECLARE @TableName sysname = N'SomeTable'; 

SELECT i.name AS IndexName 
     ,8 * SUM(s.used_page_count) AS IndexSizeKB 
FROM sys.indexes AS i 
    INNER JOIN sys.dm_db_partition_stats AS s 
     ON i.[object_id] = s.[object_id] AND i.index_id = s.index_id 
WHERE s.[object_id] = OBJECT_ID(@TableName, N'U') 
GROUP BY i.name 
ORDER BY i.name; 

SELECT i.name AS IndexName 
     ,8 * SUM(a.used_pages) AS IndexSizeKB 
FROM sys.indexes AS i 
    INNER JOIN sys.partitions AS p 
     ON i.[object_id] = p.[object_id] AND i.index_id = p.index_id 
    INNER JOIN sys.allocation_units AS a 
     ON p.partition_id = a.container_id 
WHERE i.[object_id] = OBJECT_ID(@TableName, N'U') 
GROUP BY i.name 
ORDER BY i.name; 
Cuestiones relacionadas