views:

118

answers:

4

How to list row count of each table in the database. Some equivalent of

select count(*) from table1
select count(*) from table2
...
select count(*) from tableN

I will post a solution but other approaches are welcome

A: 

The first thing that came to mind was to use sp_msForEachTable

exec sp_msforeachtable 'select count(*) from ?'

that does not list the table names though, so it can be extended to

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

The problem here is that if the database has more than 100 tables you will get the following error message:

The query has exceeded the maximum number of result sets that can be displayed in the results grid. Only the first 100 result sets are displayed in the grid.

So I ended up using table variable to store the results

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
kristof
+4  A: 

If you're using SQL Server 2005 and up, you can also use this:

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)

In my opinion, it's easier to handle than the sp_msforeachtable output.....

Marc

marc_s
thanks marc_s, that should indeed be easier to manage
kristof
A: 

If you use MySQL >4.x you can use this:

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

Keep in mind that for some storage engines, TABLE_ROWS is an approximation.

David Poblador i Garcia
he mentioned "sql-server" in his post (as a tag) which is Microsoft SQL Server
marc_s
+1  A: 

As seen here, this will return correct counts, where methods using the meta data tables will only return estimates.

    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
KM
So it sound like a compromise of using undocumented stor proc sp_msForEachTable vs using system tables with sometimes not most up to date info. +1 and thanks for the link
kristof