2009-09-18 64 views

Respuesta

230

Si está utilizando SQL Server 2005 y hasta, también se puede utilizar esto:

SELECT 
    t.NAME AS TableName, 
    i.name as indexName, 
    p.[Rows], 
    sum(a.total_pages) as TotalPages, 
    sum(a.used_pages) as UsedPages, 
    sum(a.data_pages) as DataPages, 
    (sum(a.total_pages) * 8)/1024 as TotalSpaceMB, 
    (sum(a.used_pages) * 8)/1024 as UsedSpaceMB, 
    (sum(a.data_pages) * 8)/1024 as DataSpaceMB 
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 
WHERE 
    t.NAME NOT LIKE 'dt%' AND 
    i.OBJECT_ID > 255 AND 
    i.index_id <= 1 
GROUP BY 
    t.NAME, i.object_id, i.index_id, i.name, p.[Rows] 
ORDER BY 
    object_name(i.object_id) 

En mi opinión, es más fácil de manejar que la salida sp_msforeachtable.

+0

gracias marc_s, eso debería ser más fácil de manejar – kristof

+1

¿Alguna idea de por qué está filtrando tablas con un nombre que empiece con "dt"? He visto este guión en toda la red, pero no hay explicación sobre ese criterio. ¿Todos estamos siendo trolled? – Skaue

+6

@Skaue: si instala la funcionalidad "Diagrama de base de datos" en una base de datos suya, entonces tendrá algunas tablas como 'dtProperties', etc. ya que esas son tablas de "sistema", no quiero informar sobre ellas. –

1

Lo primero que vino a la mente fue utilizar sp_msForEachTable

exec sp_msforeachtable 'select count(*) from ?' 

que no enumera los nombres de las tablas, aunque , por lo que se puede ampliar a

exec sp_msforeachtable 'select parsename(''?'', 1), count(*) from ?' 

El problema aquí es que si el d atabase tiene más de 100 mesas que obtendrá el siguiente mensaje de error:

La consulta ha excedido el máximo número de conjuntos de resultados que pueden ser que aparece en la cuadrícula de resultados. Solo se muestran los primeros 100 conjuntos de resultados en la cuadrícula.

así que terminé usando variable de tabla para almacenar los resultados

declare @stats table (n sysname, c int) 
insert into @stats 
    exec sp_msforeachtable 'select parsename(''?'', 1), count(*) from ?' 
select 
    * 
from @stats 
order by c desc 
-1

Si utiliza MySQL> 4.x puede utilizar esto:

select TABLE_NAME, TABLE_ROWS from information_schema.TABLES where TABLE_SCHEMA="test"; 

Tenga en cuenta que para algunos motores de almacenamiento, TABLE_ROWS es una aproximación.

+6

mencionó "sql-server" en su publicación (como una etiqueta) que es Microsoft SQL Server –

6

As seen here, esto devolverá recuentos correctos, donde los métodos que utilizan las tablas de metadatos solo devolverán las estimaciones.

CREATE PROCEDURE ListTableRowCounts 
    AS 
    BEGIN 
     SET NOCOUNT ON 

     CREATE TABLE #TableCounts 
     ( 
      TableName VARCHAR(500), 
      CountOf INT 
     ) 

     INSERT #TableCounts 
      EXEC sp_msForEachTable 
       'SELECT PARSENAME(''?'', 1), 
       COUNT(*) FROM ? WITH (NOLOCK)' 

     SELECT TableName , CountOf 
      FROM #TableCounts 
      ORDER BY TableName 

     DROP TABLE #TableCounts 
    END 
    GO 
+0

Por lo que parece un compromiso de usar stor proc sp_msForEachTable indocumentado vs usar tablas del sistema con información a veces no más actualizada. +1 y gracias por el enlace – kristof

73

un fragmento que encontré en http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=21021 que me ayudó:

select t.name TableName, i.rows Records 
from sysobjects t, sysindexes i 
where t.xtype = 'U' and i.id = t.id and i.indid in (0,1) 
order by TableName; 
+7

Solución mucho más simple y funciona muy bien! –

+0

una secuencia de comandos –

+1

Me gusta esta solución, aunque usaría la sintaxis 'JOIN' de sysobjects t unión interna sysindexes i en i.id = t.id y i.indid en (0, 1) donde t .xtype = 'U'' – Shnugo

11

Para obtener esa información en SQL Server Management Studio, haga clic derecho en la base de datos, a continuación, seleccione Informes -> Informes estándar -> Uso del disco por tabla.

+0

Enfoque subestimado, esto genera rápidamente un informe ordenable que muestra # filas y tamaño de datos. – tbone

-1
select T.object_id, T.name, I.indid, I.rows 
    from Sys.tables T 
    left join Sys.sysindexes I 
    on (I.id = T.object_id and (indid =1 or indid =0)) 
where T.type='U' 

Aquí indid=1 significa un índice agrupado y indid=0 es un cúmulo

+4

Hola y bienvenidos a Stack Overflow. Esta respuesta es idéntica a una que tiene [un año de antigüedad] (http://stackoverflow.com/a/14163881/458741) ya ... no hubo necesidad de publicarla nuevamente. – Ben

7
SELECT 
    T.NAME AS 'TABLE NAME', 
    P.[ROWS] AS 'NO OF ROWS' 
FROM SYS.TABLES T 
INNER JOIN SYS.PARTITIONS P ON T.OBJECT_ID=P.OBJECT_ID; 
+2

Esta consulta arrojará un resultado de filas para cada índice en cada tabla. Agregue un WHERE P.INDEX_ID IN (0,1) para limitar el conjunto de resultados de devolución a montones o índices agrupados solo cuando corresponda. –

2
sp_MSForEachTable 'DECLARE @t AS VARCHAR(MAX); 
SELECT @t = CAST(COUNT(1) as VARCHAR(MAX)) 
+ CHAR(9) + CHAR(9) + ''?'' FROM ? ; PRINT @t' 

Salida:

estudio de gestión

enter image description here

1

Bueno, afortunadamente SQL Server le da una pista sobre como hacer esto. hacer esto,

  1. iniciar una traza de SQL Server y abrir la actividad que está haciendo (filtro por su ID de inicio de sesión si usted no está solo y establecer el nombre de la aplicación a Microsoft SQL Server Management Studio), pausa rastrear y descartar cualquier resultado que haya grabado hasta ahora;
  2. Luego, haga clic derecho en una tabla y seleccione una propiedad en el menú emergente;
  3. iniciar el rastreo nuevamente;
  4. Ahora en el estudio de SQL Server Management seleccione el elemento de propiedad de almacenamiento a la izquierda;

Pausa la traza y echar un vistazo a lo que TSQL es generado por Microsoft.

En el probablemente la última consulta, verá una sentencia A partir de exec sp_executesql N'SELECT

al copiar el código que se ejecuta a Visual Studio se dará cuenta de que este código genera todos los datos de los ingenieros de Microsoft utilizan para rellenar la ventana de propiedades .

cuando haces modificaciones moderadas a esa consulta se llega a algo como esto:

SELECT 
SCHEMA_NAME(tbl.schema_id)+'.'+tbl.name as [table], --> something I added 
p.partition_number AS [PartitionNumber], 
prv.value AS [RightBoundaryValue], 
fg.name AS [FileGroupName], 
CAST(pf.boundary_value_on_right AS int) AS [RangeType], 
CAST(p.rows AS float) AS [RowCount], 
p.data_compression AS [DataCompression] 
FROM sys.tables AS tbl 
INNER JOIN sys.indexes AS idx ON idx.object_id = tbl.object_id and idx.index_id < 2 
INNER JOIN sys.partitions AS p ON p.object_id=CAST(tbl.object_id AS int) AND p.index_id=idx.index_id 
LEFT OUTER JOIN sys.destination_data_spaces AS dds ON dds.partition_scheme_id = idx.data_space_id and dds.destination_id = p.partition_number 
LEFT OUTER JOIN sys.partition_schemes AS ps ON ps.data_space_id = idx.data_space_id 
LEFT OUTER JOIN sys.partition_range_values AS prv ON prv.boundary_id = p.partition_number and prv.function_id = ps.function_id 
LEFT OUTER JOIN sys.filegroups AS fg ON fg.data_space_id = dds.data_space_id or fg.data_space_id = idx.data_space_id 
LEFT OUTER JOIN sys.partition_functions AS pf ON pf.function_id = prv.function_id 

Ahora la consulta no es perfecto y que podría actualizarla para satisfacer otras preguntas que pueda tener, el punto es, puede utilizar el conocimiento de microsoft para acceder a la mayoría de las preguntas que tiene al ejecutar los datos que le interesan y rastrear el TSQL generado utilizando el generador de perfiles.

Me gustaría pensar que los ingenieros de MS saben cómo funciona SQL Server y generará TSQL que funciona en todos los elementos con los que puede trabajar utilizando la versión en SSMS que está utilizando, por lo que es bastante bueno en una gran variedad de lanzamientos prerviouse, actual y futuro.

Y recuerde, no solo copie, trate de entenderlo bien, de lo contrario podría terminar con la solución incorrecta.

Walter

1

La respuesta aceptada no funcionó para mí en SQL Azure, aquí está one que hizo, que es súper rápido e hizo exactamente lo que quería:

select t.name, s.row_count 
from sys.tables t 
join sys.dm_db_partition_stats s 
    ON t.object_id = s.object_id 
    and t.type_desc = 'USER_TABLE' 
    and t.name not like '%dss%' 
    and s.index_id = 1 
order by s.row_count desc 
0

creo que la más corta, más rápida y más simple sería:

SELECT 
    object_name(object_id) AS [Table], 
    SUM(row_count) AS [Count] 
FROM 
    sys.dm_db_partition_stats 
WHERE 
    --object_schema_name(object_id) = 'dbo' AND 
    index_id < 2 
GROUP BY 
    object_id 
0

Usted podría intentar esto:

SELECT OBJECT_SCHEMA_NAME(ps.object_Id) AS [schemaname], 
     OBJECT_NAME(ps.object_id) AS [tablename], 
     row_count AS [rows] 
FROM sys.dm_db_partition_stats ps 
WHERE OBJECT_SCHEMA_NAME(ps.object_Id) <> 'sys' AND ps.index_id < 2 
ORDER BY 
     OBJECT_SCHEMA_NAME(ps.object_Id), 
     OBJECT_NAME(ps.object_id) 
0

Esto se acerca utiliza la concatenación de cadenas para producir una declaración con todas las tablas y su población en forma dinámica, como el ejemplo (s) dada en la pregunta original:

  SELECT COUNT(*) AS Count,'[dbo].[tbl1]' AS TableName FROM [dbo].[tbl1] 
UNION ALL SELECT COUNT(*) AS Count,'[dbo].[tbl2]' AS TableName FROM [dbo].[tbl2] 
UNION ALL SELECT... 

Por último, este se ejecuta con EXEC:

DECLARE @cmd VARCHAR(MAX)=STUFF(
        (
         SELECT 'UNION ALL SELECT COUNT(*) AS Count,''' 
           + QUOTENAME(t.TABLE_SCHEMA) + '.' + QUOTENAME(t.TABLE_NAME) 
           + ''' AS TableName FROM ' + QUOTENAME(t.TABLE_SCHEMA) + '.' + QUOTENAME(t.TABLE_NAME) 
         FROM INFORMATION_SCHEMA.TABLES AS t 
         WHERE TABLE_TYPE='BASE TABLE' 
         FOR XML PATH('') 
        ),1,10,''); 
EXEC(@cmd); 
Cuestiones relacionadas