74

Is there a way to query the DB to find out how many rows there are in all the tables?

i.e.

table1 1234
table2 222
table3 7888

Hope you can advise

shA.t
  • 16,580
  • 5
  • 54
  • 111
Lee
  • 20,034
  • 23
  • 75
  • 102
  • Extended answer for doing it in a single step: http://stackoverflow.com/questions/24707814/mysql-summarize-all-table-row-counts-in-a-single-query – gwideman Jul 11 '14 at 23:54

9 Answers9

168
SELECT 
    TABLE_NAME, 
    TABLE_ROWS 
FROM 
    `information_schema`.`tables` 
WHERE 
    `table_schema` = 'YOUR_DB_NAME';
shA.t
  • 16,580
  • 5
  • 54
  • 111
great_llama
  • 11,481
  • 4
  • 34
  • 29
  • 37
    As far as I know, row count is not stored for InnoDB tables. This query can give an approximation at most. – Álvaro González Apr 22 '10 at 16:14
  • 3
    To get the total count across 2+ tables, you can modify it: `SELECT SUM(TABLE_ROWS) FROM information_schema.tables WHERE table_schema = 'YOUR_DATABASE_NAME' && (TABLE_NAME='table1' || TABLE_NAME='table2')` – degenerate Aug 06 '14 at 19:59
  • 8
    Note: `TABLE_ROWS` may get out of sync with the current table contents, but you can update it by running `ANALYZE` ;). – shA.t Aug 30 '17 at 14:11
  • 3
    I would just add `ORDER BY TABLE_ROWS DESC` to detect the hogs. – BaseZen Jun 09 '18 at 04:34
  • I don't feel like this answer is valuable without ANALYZE first as @shA.t has mentioned. – teuber789 Jun 29 '18 at 00:21
11

Synthesising the info above and this post into one set of queries, we get a self-writing query that will give accurate row counts:

SET @tableSchema = 'my_schema';
SET SESSION group_concat_max_len = 10000000;
SET @rowCounts = (
  SELECT group_concat(CONCAT('SELECT ''',TABLE_NAME,''', COUNT(*) FROM ', TABLE_NAME) SEPARATOR ' union all ')
  FROM information_schema.tables WHERE table_schema = @tableSchema
);
PREPARE statement FROM @rowCounts;
EXECUTE statement;

-- don't run dealloc until you've exported your results ;)
DEALLOCATE PREPARE statement;
tjmcewan
  • 2,448
  • 2
  • 16
  • 11
  • 1
    Thanks. This works better than any other solutions I've found. Does exactly what I needed. – DaveEP May 25 '18 at 10:45
  • 1
    This is the only complete solution. – thejohnbackes Aug 24 '18 at 21:37
  • Yes, indeed. This should be the only correct solution. To avoid errors when you have views stored in your database, the WHERE clause should look like that: `WHERE table_schema = @tableSchema AND TABLE_TYPE != 'VIEW'`. And to get only size of your tables (not system tables): `WHERE table_schema = @tableSchema AND TABLE_TYPE = 'BASE TABLE'`. – Olgierd Dzięcielski Aug 15 '23 at 07:53
  • Yeah this should be the accepted solution, perfect, thanks – ddrake12 Aug 30 '23 at 22:10
11

The above will give you an approximation, but if you want an exact count, it can be done in two steps. First, execute a query like the following:

select concat("select '",table_name,"', count(*) from ",table_name,";") 
from `information_schema`.`tables` 
WHERE `table_schema` = '[your schema here]';

That will produce a list of SQL statements, one for each table in your database, you can then run to get an exact count.

shA.t
  • 16,580
  • 5
  • 54
  • 111
ande
  • 127
  • 1
  • 2
7
SELECT 
    table_name, 
    table_rows 
FROM 
    INFORMATION_SCHEMA.TABLES
shA.t
  • 16,580
  • 5
  • 54
  • 111
Nir
  • 24,619
  • 25
  • 81
  • 117
6

This will give you the exact Table name and count on a single list

SELECT CONCAT('SELECT ''',table_name,''', COUNT(*) FROM ', table_name, ' union all') 
      FROM information_schema.tables WHERE table_schema = 'clw';
petrichi
  • 101
  • 1
  • 6
4
select sum(cnt) from
(
select count(*) as cnt from table1
union ALL
select count(*) as cnt from table2
union ALL
select count(*) as cnt from table3 
)t1
a1ex07
  • 36,826
  • 12
  • 90
  • 103
2

It is convenient to use a stored procedure to get tables' rows. For example:

CALL database_tables_row_count('my_shop_db');

will display:

+-------------------+-----------+
| table             | row_count |
+-------------------+-----------+
| user              |         5 |
| payment           |        12 |
+-------------------+-----------+

in case there are no tables inside 'my_shop_db' you'll get:

Empty set (0.00 sec)

If you misspell the database name you'll get:

ERROR 1049 (42000): Unknown database 'my_so_db'

The same way as if you issued the statement use non_existing_db;

The stored procedure must be stored somewhere (in a database). If you store it into the current database, you will be able to use it this way

CALL database_tables_row_count('my_shop_db');

to get the results regarding any database as long you use your current database where you stored that procedure

Since such query like a count of tables' rows is quite common so you may want to store that procedure in a common database (a kind of a toolbox) for eg called admin. To create the stored procedure inside a new db:

CREATE DATABASE IF NOT EXISTS `admin`;

then switch into it:

USE `admin`;

and create the stored procedure:

DROP PROCEDURE IF EXISTS `database_tables_row_count`;

DELIMITER $$
CREATE PROCEDURE `database_tables_row_count`(IN tableSchema VARCHAR(255))
BEGIN
    DECLARE msg VARCHAR(128);

    IF (SELECT COUNT(TABLE_NAME) FROM information_schema.tables WHERE table_schema = `tableSchema`) = 0 THEN
        SET msg = CONCAT('Unknown database \'', `tableSchema`, '\'');
        SIGNAL SQLSTATE '42000' SET MESSAGE_TEXT = msg, MYSQL_ERRNO = 1049;
    END IF;

    SET SESSION group_concat_max_len = 10000000;
    SET @rowCounts = (
        SELECT group_concat(CONCAT('SELECT ''',TABLE_NAME,''' AS `table`, COUNT(*) AS `row_count` FROM ', `tableSchema`, '.', TABLE_NAME) SEPARATOR ' union all ')
        FROM information_schema.tables WHERE table_schema = `tableSchema`
        AND TABLE_TYPE = 'BASE TABLE'
    );

    IF @rowCounts IS NOT NULL THEN
        PREPARE statement FROM @rowCounts;
        EXECUTE statement;
        DEALLOCATE PREPARE statement;
    ELSE
        # if no base tables found then return an empty set
        select 1 where 0 = 1;
    END IF;

END$$
DELIMITER ;

Then to use it despite the current database:

CALL admin.database_tables_row_count('my_shop_db');

to get the results.

There is no need to create a separate database just to hold that procedure but I found useful to have a one dedicated database that acts as a kind of toolbox so I don't need to recreate procedures/views/functions for every development and every time after I used drop database...

You may want to change this line:

AND TABLE_TYPE = 'BASE TABLE'

to:

AND TABLE_TYPE IN ('BASE TABLE', 'VIEW')

if you want to get rows count also for the views.

Jimmix
  • 5,644
  • 6
  • 44
  • 71
0

Probably want this if you just want tables and no views:

SELECT TABLE_NAME, TABLE_ROWS
FROM   `information_schema`.`tables` 
WHERE  `table_schema` = 'schema'
       AND TABLE_TYPE = 'BASE TABLE';
OneSimpleGeek
  • 138
  • 11
0

Run this Query a to get results, Information Schema won't give correct results.

Select group_concat(Query SEPARATOR ' union all ') as Full_Query from (SELECT CONCAT('SELECT ''',table_name,''', COUNT(*) FROM ', table_name) as Query
FROM information_schema.tables) AS T1 into @sql from (select 
table_schema db,
table_name tablename from information_schema.tables where table_schema not in 
('performance_schema', 'mysql', 'information_schema')) t; 

Then Run-

prepare s from @sql; execute s; deallocate prepare s;