如何获取 MySQL 数据库表的大小?
Posted
技术标签:
【中文标题】如何获取 MySQL 数据库表的大小?【英文标题】:How to get the sizes of the tables of a MySQL database? 【发布时间】:2021-04-05 13:55:36 【问题描述】:我可以运行这个查询来获取 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,这只会正确计算静态大小字段的长度。您如何计算 VARCHAR
和 BLOB
类型?
@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】:如果您希望查询使用当前选定的数据库。只需复制粘贴此查询。 (无需修改)
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;【参考方案5】:
所有表格的大小:
假设您的数据库或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)
【讨论】:
【参考方案6】:有一种使用 Workbench 获取许多信息的简单方法:
右键单击架构名称,然后单击“架构检查器”。
在结果窗口中,您有许多选项卡。第一个标签 “信息”显示了对数据库大小的粗略估计,以 MB 为单位。
第二个选项卡“表格”显示每个表格的数据长度和其他详细信息。
【讨论】:
我的 Mac 客户端 v 6.0.9 上没有“信息”选项卡 太棒了!!!在 MySQL Workbench 中,每个表还有一个“表检查器”。不是很快,但非常方便!【参考方案7】:尝试以下 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
【讨论】:
【参考方案8】:这是使用 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
【讨论】:
【参考方案9】:如果您使用的是 phpmyadmin,那么只需转到表结构
例如
Space usage
Data 1.5 MiB
Index 0 B
Total 1.5 Mi
【讨论】:
【参考方案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】:另一种显示行数和占用空间并对其进行排序的方式。
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”。
【讨论】:
【参考方案12】:如果您有ssh
访问权限,您可能只想尝试du -hc /var/lib/mysql
(或其他datadir
,如您在my.cnf
中设置的那样)。
【讨论】:
终于有了一个不依赖于information_schema的答案。就我而言,它报告了 660MB,而文件系统的实际大小为 1.8GB【参考方案13】:我发现现有的答案实际上并没有给出磁盘上表的大小,这更有帮助。 与基于 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 权限才能从此表中进行选择。【参考方案14】: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上测试过
【讨论】:
【参考方案15】:这应该在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 为什么还被封号? 抱歉,我不知道答案 - 我不是版主。【参考方案16】:最后计算数据库的总大小:
(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"
)
【讨论】:
【参考方案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 数据库表的大小?的主要内容,如果未能解决你的问题,请参考以下文章