JPashs
JPashs

Reputation: 13886

How can I get the sizes of the tables of a MySQL database?

I can run this query to get the sizes of all tables in a MySQL database:

show table status from myDatabaseName;

I would like some help in understanding the results. I am looking for tables with the largest sizes.

Which column should I look at?

Upvotes: 1183

Views: 979177

Answers (21)

Almis
Almis

Reputation: 3819

If you are using phpMyAdmin, then just go to the table structure.

E.g.,

Space usage
Data    1.5    MiB
Index     0    B
Total   1.5    Mi

Upvotes: 6

user1380599
user1380599

Reputation: 203

Here’s another way of working this out from using the Bash command line.

for i in `mysql -NB -e 'show databases'`; do echo $i; mysql -e "SELECT table_name AS 'Tables', round(((data_length+index_length)/1024/1024),2) 'Size in MB' FROM information_schema.TABLES WHERE table_schema =\"$i\" ORDER BY (data_length + index_length) DESC" ; done

Upvotes: 7

Gank
Gank

Reputation: 4667

SELECT 
    table_name AS "Table",  
    round(((data_length + index_length) / 1024 / 1024), 2) as size   
FROM information_schema.TABLES  
WHERE table_schema = "YOUR_DATABASE_NAME"  
ORDER BY size DESC; 

This sorts the sizes (database size in MB).

Upvotes: 64

user1012513
user1012513

Reputation: 2355

Try this command: Replace your_database_name with the name of your MySQL database.

SELECT 
    table_name AS `Table`,
    round(((data_length + index_length) / 1024 / 1024), 2) `Size in MB`
FROM information_schema.tables
WHERE table_schema = 'your_database_name'
ORDER BY `Size in MB` DESC;

Upvotes: 6

Hamid Raza
Hamid Raza

Reputation: 32

Here we can find the database size from the information_schema.tables default database in MySQL server where we can find metadata of MySql Server databases.

Query for see tables size:

SELECT 
    table_name AS `Table`,
    ROUND(((data_length + index_length) / 1024 / 1024), 2) AS `Size (MB)`
FROM information_schema.tables
WHERE table_schema = 'your_database_name'
ORDER BY (data_length + index_length) DESC;

Query for see all database size:

SELECT 
    table_schema AS `Database`,
    ROUND(SUM(data_length + index_length) / (1024 * 1024), 2) AS `Size (MB)`
FROM information_schema.tables
WHERE table_schema = 'your_database_name'
GROUP BY table_schema;

Upvotes: 0

Zach
Zach

Reputation: 566

Replace "DB_NAME" with the name of your database:

SELECT 
    table_schema AS `Database`, 
    table_name AS `Table`, 
    ROUND(((data_length + index_length) / 1024 / 1024)) as `Size in MB` 
FROM information_schema.TABLES `enter code here`
WHERE table_schema = "$DB_NAME"
ORDER BY (data_length + index_length) DESC;

Upvotes: 2

irsis
irsis

Reputation: 1054

This is just a note for future reference. All answers are relying on the I_S.TABLES. It doesn't tell correct size for instance if you have blob fields in the table. LOB pages are stored in external pages so they are not accounted in the clustered index. In fact there is a note :

For NDB tables, the output of this statement shows appropriate values for the AVG_ROW_LENGTH and DATA_LENGTH columns, with the exception that BLOB columns are not taken into account.

I found to be true for InnoDB as well.

I have created community Bug for the same.

Upvotes: 1

Sumith Harshan
Sumith Harshan

Reputation: 6445

SELECT TABLE_NAME AS "Table Name", 
table_rows AS "Quant of Rows", ROUND( (
data_length + index_length
) /1024, 2 ) AS "Total Size Kb"
FROM information_schema.TABLES
WHERE information_schema.TABLES.table_schema = 'YOUR SCHEMA NAME/DATABASE NAME HERE'
LIMIT 0 , 30

You can get schema name from "information_schema" -> SCHEMATA table -> "SCHEMA_NAME" column


Additional You can get size of the mysql databases as following.

SELECT table_schema "DB Name", 
Round(Sum(data_length + index_length) / 1024 / 1024, 1) "DB Size in MB" 
FROM   information_schema.tables 
GROUP  BY table_schema
ORDER BY `DB Size in MB` DESC;

Result

DB Name              |      DB Size in MB

mydatabase_wrdp             39.1
information_schema          0.0

You can get additional details in here.

Upvotes: 139

Thibault Richard
Thibault Richard

Reputation: 382

I've made this shell script to keep a track of table size (in bytes and in number of rows)

#!/bin/sh

export MYSQL_PWD=XXXXXXXX
TABLES="table1 table2 table3"

for TABLE in $TABLES;
do
        FILEPATH=/var/lib/mysql/DBNAME/$TABLE.ibd
        TABLESIZE=`wc -c $FILEPATH | awk '{print $1}'`
        #Size in Bytes
        mysql -D scarprd_self -e "INSERT INTO tables_sizes (table_name,table_size,measurement_type) VALUES ('$TABLE', '$TABLESIZE', 'BYTES');"
        #Size in rows
        ROWSCOUNT=$(mysql -D scarprd_self -e "SELECT COUNT(*) AS ROWSCOUNT FROM $TABLE;")
        ROWSCOUNT=${ROWSCOUNT//ROWSCOUNT/}
        mysql -D scarprd_self -e "INSERT INTO tables_sizes (table_name,table_size,measurement_type) VALUES ('$TABLE', '$ROWSCOUNT', 'ROWSCOUNT');"
        mysql -D scarprd_self -e "DELETE FROM tables_sizes WHERE measurement_datetime < TIMESTAMP(DATE_SUB(NOW(), INTERVAL 365 DAY));"
done

It presuppose to have this MySQL table

CREATE TABLE `tables_sizes` (
  `table_name` VARCHAR(128) NOT NULL,
  `table_size` VARCHAR(25) NOT NULL,
  `measurement_type` VARCHAR(10) NOT NULL CHECK (measurement_type IN ('BYTES','ROWSCOUNT')),
  `measurement_datetime` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP()
) ENGINE=INNODB DEFAULT CHARSET=utf8

Upvotes: -2

Nurul Akter Towhid
Nurul Akter Towhid

Reputation: 3246

  • Size of all tables:

    Suppose your database or TABLE_SCHEMA name is "news_alert". Then this query will show the size of all tables in the database.

    SELECT
      TABLE_NAME AS `Table`,
      ROUND(((DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024),2) AS `Size (MB)`
    FROM
      information_schema.TABLES
    WHERE
      TABLE_SCHEMA = "news_alert"
    ORDER BY
      (DATA_LENGTH + INDEX_LENGTH)
    DESC;
    

    Output:

        +---------+-----------+
        | Table   | Size (MB) |
        +---------+-----------+
        | news    |      0.08 |
        | keyword |      0.02 |
        +---------+-----------+
        2 rows in set (0.00 sec)
    
  • For the specific table:

    Suppose your TABLE_NAME is "news". Then SQL query will be-

    SELECT
      TABLE_NAME AS `Table`,
      ROUND(((DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024),2) AS `Size (MB)`
    FROM
      information_schema.TABLES
    WHERE
        TABLE_SCHEMA = "news_alert"
      AND
        TABLE_NAME = "news"
    ORDER BY
      (DATA_LENGTH + INDEX_LENGTH)
    DESC;
    

    Output:

    +-------+-----------+
    | Table | Size (MB) |
    +-------+-----------+
    | news  |      0.08 |
    +-------+-----------+
    1 row in set (0.00 sec)
    

Upvotes: 37

William
William

Reputation: 61

This should be tested in mysql, not postgresql:

SELECT table_schema, # "DB Name", 
Round(Sum(data_length + index_length) / 1024 / 1024, 1) # "DB Size in MB" 
FROM   information_schema.tables 
GROUP  BY table_schema; 

Upvotes: 3

Ryum Aayur
Ryum Aayur

Reputation: 185

I find the existing answers don't actually give the size of tables on the disk, which is more helpful. This query gives more accurate disk estimate compared to table size based on data_length & index. I had to use this for an AWS RDS instance where you cannot physically examine the disk and check file sizes.

select NAME as TABLENAME,FILE_SIZE/(1024*1024*1024) as ACTUAL_FILE_SIZE_GB
, round(((data_length + index_length) / 1024 / 1024/1024), 2) as REPORTED_TABLE_SIZE_GB 
from INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES s
join INFORMATION_SCHEMA.TABLES t 
on NAME = Concat(table_schema,'/',table_name)
order by FILE_SIZE desc

Upvotes: 14

William
William

Reputation: 61

SELECT TABLE_NAME AS table_name, 
table_rows AS QuantofRows, 
ROUND((data_length + index_length) /1024, 2 ) AS total_size_kb 
FROM information_schema.TABLES
WHERE information_schema.TABLES.table_schema = 'db'
ORDER BY (data_length + index_length) DESC; 

all 2 above is tested on mysql

Upvotes: 2

MINGSONG HU
MINGSONG HU

Reputation: 11

Calculate the total size of the database at the end:

(SELECT 
  table_name AS `Table`, 
  round(((data_length + index_length) / 1024 / 1024), 2) `Size in MB` 
  FROM information_schema.TABLES 
  WHERE table_schema = "$DB_NAME"
)
UNION ALL
(SELECT 
  'TOTAL:',
  SUM(round(((data_length + index_length) / 1024 / 1024), 2) )
  FROM information_schema.TABLES 
  WHERE table_schema = "$DB_NAME"
)

Upvotes: 1

zainengineer
zainengineer

Reputation: 13889

If you want a query to use currently selected database. simply copy paste this query. (No modification required)

SELECT table_name ,
  round(((data_length + index_length) / 1024 / 1024), 2) as SIZE_MB
FROM information_schema.TABLES
WHERE table_schema = DATABASE() ORDER BY SIZE_MB DESC;

Upvotes: 48

exic
exic

Reputation: 2678

If you have ssh access, you might want to simply try du -hc /var/lib/mysql (or different datadir, as set in your my.cnf) as well.

Upvotes: 4

dev101
dev101

Reputation: 1369

Adapted from ChapMic's answer to suite my particular need.

Only specify your database name, then sort all the tables in descending order - from LARGEST to SMALLEST table inside selected database. Needs only 1 variable to be replaced = your database name.

SELECT 
table_name AS `Table`, 
round(((data_length + index_length) / 1024 / 1024), 2) AS `size`
FROM information_schema.TABLES 
WHERE table_schema = "YOUR_DATABASE_NAME_HERE"
ORDER BY size DESC;

Upvotes: 5

Nav
Nav

Reputation: 20698

Another way of showing the number of rows and space occupied and ordering by it.

SELECT
     table_schema as `Database`,
     table_name AS `Table`,
     table_rows AS "Quant of Rows",
     round(((data_length + index_length) / 1024 / 1024/ 1024), 2) `Size in GB`
FROM information_schema.TABLES
WHERE table_schema = 'yourDatabaseName'
ORDER BY (data_length + index_length) DESC;  

The only string you have to substitute in this query is "yourDatabaseName".

Upvotes: 4

kenorb
kenorb

Reputation: 166795

Try the following shell command (replace DB_NAME with your database name):

mysql -uroot <<<"SELECT table_name AS 'Tables', round(((data_length + index_length) / 1024 / 1024), 2) 'Size in MB' FROM information_schema.TABLES WHERE table_schema = \"DB_NAME\" ORDER BY (data_length + index_length) DESC;" | head

For Drupal/drush solution, check the following example script which will display the biggest tables in use:

#!/bin/sh
DB_NAME=$(drush status --fields=db-name --field-labels=0 | tr -d '\r\n ')
drush sqlq "SELECT table_name AS 'Tables', round(((data_length + index_length) / 1024 / 1024), 2) 'Size in MB' FROM information_schema.TABLES WHERE table_schema = \"${DB_NAME}\" ORDER BY (data_length + index_length) DESC;" | head -n20

Upvotes: 8

ChapMic
ChapMic

Reputation: 28144

You can use this query to show the size of a table (although you need to substitute the variables first):

SELECT 
    table_name AS `Table`, 
    round(((data_length + index_length) / 1024 / 1024), 2) `Size in MB` 
FROM information_schema.TABLES 
WHERE table_schema = "$DB_NAME"
    AND table_name = "$TABLE_NAME";

or this query to list the size of every table in every database, largest first:

SELECT 
     table_schema as `Database`, 
     table_name AS `Table`, 
     round(((data_length + index_length) / 1024 / 1024), 2) `Size in MB` 
FROM information_schema.TABLES 
ORDER BY (data_length + index_length) DESC;

Upvotes: 2442

Guppy
Guppy

Reputation: 426

There is an easy way to get many informations using Workbench:

  • Right-click the schema name and click "Schema inspector".

  • In the resulting window you have a number of tabs. The first tab "Info" shows a rough estimate of the database size in MB.

  • The second tab, "Tables", shows Data length and other details for each table.

Upvotes: 20

Related Questions