如何获取 MySQL 数据库表的大小?

Posted

技术标签:

【中文标题】如何获取 MySQL 数据库表的大小?【英文标题】:How to get the sizes of the tables of a MySQL database? 【发布时间】:2012-03-26 02:03:38 【问题描述】:

我可以运行这个查询来获取 mysql 数据库中所有表的大小:

show table status from myDatabaseName;

我需要一些帮助来理解结果。我正在寻找尺寸最大的桌子。

我应该看哪一栏?

【问题讨论】:

大小是什么意思?行数?磁盘上占用的字节数? @Mark 我想要磁盘大小是正确的方法吗? # du -sh /mnt/mysql_data/openx/f_scraper_banner_details.MYI 79G /mnt/mysql_data/openx/f_scraper_banner_details.MYI 相关,如果感兴趣,我在this Answer写了一个Describe All Tables 【参考方案1】:

您可以使用此查询来显示表的大小(尽管您需要先替换变量):

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";

或者这个查询列出每个数据库中每个表的大小,最大的在前:

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;

【讨论】:

谢谢,它工作得很好,虽然我不确定它是否考虑到 Blob。 注意,你也可以使用“IN”来指定多个表,例如AND table_name IN ('table_1', 'table_2', 'table_3'); AFAICT,这只会正确计算静态大小字段的长度。您如何计算 VARCHARBLOB 类型? @kasimir 在某些时候,世界变得混乱,一些标准组织和硬件制造商决定最好在十进制系统上定义千字节。 IEC 标准现在将基本的 2 千字节(1024 字节)称为千字节 (KiB)。无论如何,MySQL 不知道,所以如果你想要 IEC 十进制千字节,除以 1000。 这适用于 InnoDB 存储引擎吗?根据此处的 mysql 文档 - dev.mysql.com/doc/refman/5.7/en/show-table-status.html,该引擎的 data_length 字段包含聚集索引的大小。这不能正确地表示数据的大小。会吗?【参考方案2】:
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

您可以从“information_schema” -> SCHEMATA 表 -> “SCHEMA_NAME” 列中获取架构名称


附加 您可以获得mysql 数据库的大小,如下所示。

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;

结果

DB Name              |      DB Size in MB

mydatabase_wrdp             39.1
information_schema          0.0

你可以get additional details in here.

【讨论】:

【参考方案3】:
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; 

这对大小进行排序(以 MB 为单位的 DB 大小)。

【讨论】:

【参考方案4】:

尝试以下 shell 命令(将 DB_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

对于 Drupal/drush 解决方案,请检查以下示例脚本,该脚本将显示正在使用的最大表:

#!/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

【讨论】:

【参考方案5】:

这是使用 bash 命令行解决此问题的另一种方法。

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

【讨论】:

【参考方案6】:

有一种使用 Workbench 获取许多信息的简单方法:

右键单击架构名称,然后单击“架构检查器”。

在结果窗口中有许多选项卡。第一个标签 “信息”显示了对数据库大小的粗略估计,以 MB 为单位。

第二个选项卡“表格”显示每个表格的数据长度和其他详细信息。

【讨论】:

我的 Mac 客户端 v 6.0.9 上没有“信息”选项卡 太棒了!!!在 MySQL Workbench 中,每个表还有一个“表检查器”。不是很快,但非常方便!【参考方案7】:

如果您使用的是 phpmyadmin,那么只需转到表结构

例如

Space usage
Data    1.5 MiB
Index   0   B
Total   1.5 Mi

【讨论】:

【参考方案8】:

另一种显示行数和占用空间并对其进行排序的方式。

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;  

您必须在此查询中替换的唯一字符串是“yourDatabaseName”。

【讨论】:

【参考方案9】:

如果您希望查询使用当前选定的数据库。只需复制粘贴此查询。 (无需修改)

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;

【讨论】:

甚至更短(没有子查询):SELECT table_name, round(((data_length + index_length) / 1024 / 1024), 2) SIZE_MB FROM information_schema.TABLES WHERE table_schema=DATABASE() ORDER BY (data_length + index_length) ASC;【参考方案10】:

改编自 ChapMic 的回答以满足我的特殊需求。

仅指定您的数据库名称,然后按降序对所有表进行排序 - 从选定数据库中的 LARGEST 到 SMALLEST 表。只需要替换 1 个变量 = 您的数据库名称。

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;

【讨论】:

【参考方案11】:

如果您有ssh 访问权限,您可能只想尝试du -hc /var/lib/mysql(或其他datadir,如您在my.cnf 中设置的那样)。

【讨论】:

终于有了一个不依赖于information_schema的答案。就我而言,它报告了 660MB,而文件系统的实际大小为 1.8GB【参考方案12】:

所有表格的大小:

假设您的数据库或TABLE_SCHEMA 名称是“news_alert”。那么这个查询将显示数据库中所有表的大小。

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;

输出:

    +---------+-----------+
    | Table   | Size (MB) |
    +---------+-----------+
    | news    |      0.08 |
    | keyword |      0.02 |
    +---------+-----------+
    2 rows in set (0.00 sec)

具体表:

假设您的TABLE_NAME“新闻”。然后 SQL 查询将是-

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;

输出:

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

【讨论】:

【参考方案13】:

最后计算数据库的总大小:

(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"
)

【讨论】:

【参考方案14】:

这应该在mysql中测试,而不是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; 

【讨论】:

虽然这可能会回答作者的问题,但它缺少一些解释性文字和/或文档链接。如果没有围绕它们的一些短语,原始代码 sn-ps 并不是很有帮助。您可能还会发现how to write a good answer 非常有帮助。请编辑您的答案 - From Review @Nick 为什么还被封号? 抱歉,我不知道答案 - 我不是版主。【参考方案15】:
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; 

以上2个都在mysql上测试过

【讨论】:

【参考方案16】:

我发现现有的答案实际上并没有给出磁盘上表的大小,这更有帮助。 与基于 data_length 的表大小相比,此查询提供更准确的磁盘估计 & 指数。我不得不将它用于 AWS RDS 实例,在该实例中您无法物理检查磁盘并检查文件大小。

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

【讨论】:

这应该是答案,至少对于 INNODB 来说。如果您有大的行外数据字段(如 blob),则仅将 DATA_LENGTH、INDEX_LENGTH 和 DATA_FREE 相加不会获得磁盘上的大小。对于 INNODB,您确实需要使用 INNDB_SYS_TABLESPACES.FILE_SIZE 来准确读取磁盘大小,但您还需要 PROCESS 权限才能从此表中进行选择。【参考方案17】:
select x.dbname as db_name, x.table_name as table_name, x.bytesize as the_size from
  (select
     table_schema as dbname,
     sum(index_length+data_length) as bytesize,
     table_name
   from
     information_schema.tables
   group by table_schema
  ) x
where
  x.bytesize > 999999
order by x.bytesize desc;

【讨论】:

【参考方案18】:

我制作了这个 shell 脚本来跟踪表大小(以字节和行数为单位)

#!/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

假设有这个 MySQL 表

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

【讨论】:

以上是关于如何获取 MySQL 数据库表的大小?的主要内容,如果未能解决你的问题,请参考以下文章

如何获取到mysql的某个数据库数据的大小和索引的大小是多少M?

如何获取 HBase 表的 HFile 大小?

如何从mysql数据库中获取一个表的表结构

如何在 PHP 中获取 MySQL 表的最后插入 ID?

如何使用 javascript 获取脚本和样式表的文件大小

用JDBC操作MySQL——获取表的大小