MySQL Information Schema  /  The INFORMATION_SCHEMA TABLES Table


The TABLES table provides information about tables in databases.

ENGINEEngineMySQL extension
VERSIONVersionThe version number of the table's .frm file, MySQL extension
ROW_FORMATRow_formatMySQL extension
TABLE_ROWSRowsMySQL extension
AVG_ROW_LENGTHAvg_row_lengthMySQL extension
DATA_LENGTHData_lengthMySQL extension
MAX_DATA_LENGTHMax_data_lengthMySQL extension
INDEX_LENGTHIndex_lengthMySQL extension
DATA_FREEData_freeMySQL extension
AUTO_INCREMENTAuto_incrementMySQL extension
CREATE_TIMECreate_timeMySQL extension
UPDATE_TIMEUpdate_timeMySQL extension
CHECK_TIMECheck_timeMySQL extension
TABLE_COLLATIONCollationMySQL extension
CHECKSUMChecksumMySQL extension
CREATE_OPTIONSCreate_optionsMySQL extension
TABLE_COMMENTCommentMySQL extension


  • Refer to SHOW TABLE STATUS for field descriptions.

  • TABLE_SCHEMA and TABLE_NAME are a single field in a SHOW display, for example Table_in_db1.

  • TABLE_TYPE should be BASE TABLE or VIEW. The TABLES table does not list TEMPORARY tables.

  • For partitioned tables, the ENGINE column shows the name of the storage engine used by all partitions. (Previously, this column showed PARTITION for such tables.)

  • The TABLE_ROWS column is NULL if the table is in the INFORMATION_SCHEMA database.

    For InnoDB tables, the row count is only a rough estimate used in SQL optimization. (This is also true if the InnoDB table is partitioned.)

  • The DATA_FREE column shows the free space in bytes for InnoDB tables.

  • UPDATE_TIME displays a timestamp value for the last UPDATE, INSERT, or DELETE performed on InnoDB tables that are not partitioned. For MVCC, the timestamp value reflects the COMMIT time, which is considered the last update time. Timestamps are not persisted when the server is restarted or when the table is evicted from the InnoDB data dictionary cache.

    The UPDATE_TIME column also shows this information for partitioned InnoDB tables.

  • For partitioned InnoDB tables, the CHECK_TIME column is always NULL.

  • We have nothing for the table's default character set. TABLE_COLLATION is close, because collation names begin with a character set name.

  • The CREATE_OPTIONS column shows partitioned if the table is partitioned.

The following statements are equivalent:

  WHERE table_schema = 'db_name'
  [AND table_name LIKE 'wild']
  FROM db_name
  [LIKE 'wild']

User Comments
  Posted by Leslie I'Anson on February 11, 2009
My understanding of calculating database size is to add the size of the tables to the size of the indexes; database = table(s) + index(es).

SELECT concat( table_schema, '.', table_name ) table_name,
concat( round( data_length / ( 1024 *1024 ) , 2 ) , 'M' ) data_length,
concat( round( index_length / ( 1024 *1024 ) , 2 ) , 'M' ) index_length,
concat( round( round( data_length + index_length ) / ( 1024 *1024 ) , 2 ) , 'M' ) total_size
FROM information_schema.TABLES
ORDER BY data_length DESC;

I've completed some rudimentary tests which seem to confirm this, at least in the case of MySQL databases.

Feedback welcomed!
  Posted by Aleksandar Kostadinov on October 12, 2009
Better would be 'ORDER BY ( data_length + index_length ) DESC' to get proper ordering. As well you can skip the inner round in total_size calculation.
Additionally engine type should be observed. One would care about certain types of tables. For example memory or non-memory. Unfortunately I can't see a consistent way to tell how much real disk space is occupied by a database.

Thanks for the expression though!

Following should show size per database:
SELECT table_schema 'database',
concat( round( sum( data_length + index_length ) / ( 1024 *1024 ) , 2 ) , 'M' ) size
FROM information_schema.TABLES
GROUP BY table_schema;
  Posted by Kalina Detko on September 2, 2010
TABLE_ROWS (and perhaps some other columns in INFORMATION_SCHEMA.TABLES) may get out of sync with the current table contents, but you can update it by running ANALYZE.
  Posted by Naref Szolik on May 27, 2012
UPDATE_TIME only stores values for a subset of the available table storage engines.
  Posted by Chris Calender on March 7, 2013
UPDATE_TIME works for MyISAM, not InnoDB.

From my tests, it updated the timestamp on both DML and DDL operations.
  Posted by Jeff Rule on October 25, 2017
You need to include data_free in your space calculations. This is expecially necessary if you are doing deletes. If you are doing large deletes, your numbers are going to be off by a large amount.

TOTAL_SIZE_ON_DISK= data_length+index_length+data_free
  Posted by Andy Schmidt on October 31, 2017
For INNO_DB tables, the CREATE_TIME column represents the timestamp of the .frm file, which will change for SOME "ALTER" commands, but not all. For other "ALTER" commands the last_update column of MySQL.INNO_DB_TABLE_STATS will change.

Therefore I use the larger of both values to more reliably detect schema changes:

( SELECT `last_update` FROM `mysql`.`innodb_table_stats` WHERE `database_name` = DATABASE() AND `table_name` = 'mytablename' )
) AS last_altered;
Sign Up Login You must be logged in to post a comment.