MySQL查看表行数
MySQL查看表行数
引言
评估表规模、判断是否需要分表、统计数据量时都要看行数。COUNT(*)最准但大表慢,information_schema的TABLE_ROWS快但InnoDB是估算值,两个手段按场景选。
精确统计:COUNT(*)
SELECT COUNT(*) FROM users;
精确返回真实行数,MyISAM直接读元数据很快,InnoDB要逐行扫描,大表千万级以上会锁读、耗时长。
带条件统计
SELECT COUNT(*) FROM orders WHERE status = 1;
统计满足条件的行数,WHERE命中索引时走索引扫描,比全表快。
估算行数:information_schema
SELECT TABLE_NAME, TABLE_ROWS
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'blog' AND TABLE_NAME = 'users';
秒出结果,适合先摸底表规模,但InnoDB的TABLE_ROWS是基于采样的估算值,可能和真实值差10%到20%。
一次查看库里所有表行数
SELECT TABLE_NAME, TABLE_ROWS, DATA_LENGTH/1024/1024 AS data_mb
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'blog'
ORDER BY TABLE_ROWS DESC;
按行数排序,快速找出最大的几张表,配合DATA_LENGTH看占用空间。
大表COUNT优化思路
- 先看估算值判断量级,需要精确再COUNT;
- COUNT(*)走二级索引,别COUNT(主键)以外的可空字段;
- 历史归档、分表后单表控制在千万行以内;
- 实时统计用缓存或汇总表,不在线上大表直接COUNT。
注意事项
- InnoDB的COUNT(*)不加WHERE返回约数,精确值必须扫描;
- information_schema的TABLE_ROWS只是估算,别当准确值用于对账;
- 大表COUNT期间会产生一致性读,占用缓冲池,避开高峰;
- 表刚大量增删后元数据统计信息可能陈旧,先ANALYZE TABLE刷新;
- MyISAM的TABLE_ROWS是精确值,和InnoDB机制不同;
- 统计行数别用COUNT(1)和COUNT(*)纠结,性能基本一致。
总结
COUNT()精确统计行数,大InnoDB表慢且耗资源;information_schema.TABLE_ROWS秒出估算值用于摸底。先看估算判断表规模,需要精确再COUNT(),条件统计尽量走索引。大表COUNT避开业务高峰,增删数据后先ANALYZE TABLE刷新元数据。实时报表建议走汇总表或缓存,避免线上大表反复全表扫描。
MySQL查看数据库列表
MySQL查看数据库列表
引言
刚连上一台MySQL服务器,先要看实例上有哪些库、当前账号能访问哪些库。SHOW DATABASES是最基础的入口,配合information_schema可拿到库名、字符集、容量等完整信息。
列出所有数据库
SHOW DATABASES;
列出当前账号有权限看到的全部库,看不到的库是权限不足,不代表不存在。
查看当前所在库
SELECT DATABASE();
切换库之前先确认当前连接落在哪个库,避免写SQL操作错库。
切换数据库
USE mydb;
切库后后续不加库名的表操作都落在mydb。
查库字符集和排序规则
SELECT SCHEMA_NAME, DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME
FROM information_schema.SCHEMATA;
拿到每个库的默认字符集,排查乱码时先看这里。
查看库占用空间
SELECT table_schema,
ROUND(SUM(data_length+index_length)/1024/1024,2) AS size_mb
FROM information_schema.tables
GROUP BY table_schema
ORDER BY size_mb DESC;
按库汇总数据和索引大小,快速找出占空间大户。
注意事项
- SHOW DATABASES只显示有权限的库,根账号才看全;
- information_schema是系统库,不要往里写业务数据;
- 新库建库时指定utf8mb4,避免emoji乱码;
- 删库DROP DATABASE不可逆,先备份再操作;
- 多实例用端口区分,别把实例和库混淆;
- 脚本里用SELECT SCHEMA_NAME批量遍历,比SHOW好解析。
总结
SHOW DATABASES列库,SELECT DATABASE()看当前库,USE切库,information_schema.SCHEMATA查字符集,按table_schema聚合查容量。先确认当前库再写SQL,建库统一utf8mb4,删库前务必备份,脚本批量处理优先走information_schema。
MySQL查看数据库大小,表占用空间
前言
磁盘快满了,不知道哪个库哪个表占空间大。本文教你查MySQL数据库和表的大小。
一、查看所有数据库大小
SELECT
table_schema AS '数据库名',
ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS '大小(MB)'
FROM information_schema.tables
GROUP BY table_schema
ORDER BY SUM(data_length + index_length) DESC;
输出:
| 数据库名 | 大小(MB) |
|---|---|
| mydb | 512.34 |
| test | 128.56 |
| mysql | 10.24 |
二、查看某个数据库的所有表大小
SELECT
table_name AS '表名',
ROUND(((data_length + index_length) / 1024 / 1024), 2) AS '大小(MB)',
table_rows AS '行数'
FROM information_schema.tables
WHERE table_schema = 'mydb'
ORDER BY (data_length + index_length) DESC;
把 mydb 换成你的数据库名。
三、查看单个表大小
SELECT
table_name AS '表名',
ROUND((data_length) / 1024 / 1024, 2) AS '数据大小(MB)',
ROUND((index_length) / 1024 / 1024, 2) AS '索引大小(MB)',
table_rows AS '行数'
FROM information_schema.tables
WHERE table_schema = 'mydb' AND table_name = 'users';
四、查看所有表大小(按大小排序)
SELECT
table_schema AS '数据库',
table_name AS '表名',
ROUND(((data_length + index_length) / 1024 / 1024), 2) AS '大小(MB)',
table_rows AS '行数'
FROM information_schema.tables
ORDER BY (data_length + index_length) DESC
LIMIT 20;
只看前20大的表。
五、用命令行查看
查看数据目录
du -sh /var/lib/mysql/
查看某个库的大小
du -sh /var/lib/mysql/mydb/
查看所有库的大小
du -sh /var/lib/mysql/*/
六、常用场景
场景1:磁盘满了,找大表
SELECT
table_schema AS '数据库',
table_name AS '表名',
ROUND(((data_length + index_length) / 1024 / 1024), 2) AS '大小(MB)'
FROM information_schema.tables
ORDER BY (data_length + index_length) DESC
LIMIT 10;
找出最大的10个表。
场景2:表很大,想知道数据和索引各占多少
SELECT
table_name AS '表名',
ROUND(data_length / 1024 / 1024, 2) AS '数据(MB)',
ROUND(index_length / 1024 / 1024, 2) AS '索引(MB)'
FROM information_schema.tables
WHERE table_schema = 'mydb';
场景3:清理无用数据,释放空间
删了很多数据,但磁盘空间没释放。
原因: InnoDB删数据后不会自动释放磁盘空间。
解决: 优化表:
OPTIMIZE TABLE users;
常见坑
坑1:table_rows不准
InnoDB的table_rows是估算值,不是精确值。
原因: InnoDB是多版本的,统计信息不精确。
解决: 要精确行数用 SELECT COUNT(*) FROM 表名;
坑2:删了数据空间没释放
DELETE删了很多行,但文件大小没变。
原因: InnoDB的表空间不会自动收缩。
解决: OPTIMIZE TABLE 表名; 或者重建表。
坑3:临时表占空间
performance_schema等系统库也占空间。
解决: 正常现象,不用管。
坑4:ibdata1文件很大
共享表空间文件很大,但不知道里面是什么。
原因: 所有InnoDB表都存在一个文件里。
解决: 开 innodb_file_per_table,每个表独立文件。
总结
常用查询:
- 查所有库大小:
GROUP BY table_schema - 查某库所有表:
WHERE table_schema='库名' - 查某表大小:
WHERE table_schema='库名' AND table_name='表名'
记住: 磁盘满了先查information_schema.tables找大表。
遇到问题加QQ23979811 协助处理
MySQL查看数据库大小和表大小命令
前言
做运维的同学经常会遇到这种情况:服务器磁盘突然满了,不知道是哪个数据库或者哪张表占了这么多空间。或者想知道自己的数据库现在有多大了,好提前规划扩容。
这时候就需要用SQL命令来查看数据库和表的大小了。很多新手同学不知道怎么查,只能傻乎乎的用du命令看整个data目录的大小,看不到具体是哪个数据库或哪张表占了空间。
这篇文章就把MySQL查看数据库大小和表大小的常用SQL命令都整理出来,以后遇到磁盘满了的问题就能快速定位了。
一、查看所有数据库的大小
如果你想知道MySQL里每个数据库分别占了多少空间,可以执行下面这个SQL:
SELECT
table_schema AS '数据库名',
ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS '大小(MB)'
FROM information_schema.tables
GROUP BY table_schema
ORDER BY SUM(data_length + index_length) DESC;
执行完之后会列出所有数据库的大小,单位是MB,从大到小排序。这样你一眼就能看出来哪个数据库最占空间了。
二、查看指定数据库的大小
如果你只想看某个数据库的大小,比如testdb数据库,可以执行:
SELECT
ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS '数据库大小(MB)'
FROM information_schema.tables
WHERE table_schema = 'testdb';
把testdb换成你要查询的数据库名就行。
三、查看数据库里所有表的大小
知道了哪个数据库大,接下来就要看这个数据库里哪张表最大了。执行下面这个SQL:
SELECT
table_name AS '表名',
table_rows AS '行数',
ROUND((data_length + index_length) / 1024 / 1024, 2) AS '大小(MB)'
FROM information_schema.tables
WHERE table_schema = 'testdb'
ORDER BY (data_length + index_length) DESC;
这样就能列出testdb数据库里所有表的大小,从大到小排序。你一眼就能看出来哪张表最占空间了。
四、查看单张表的大小
如果你只想看某一张表的大小,比如users表,可以执行:
SELECT
table_name AS '表名',
table_rows AS '行数',
ROUND((data_length + index_length) / 1024 / 1024, 2) AS '大小(MB)'
FROM information_schema.tables
WHERE table_schema = 'testdb'
AND table_name = 'users';
五、查看表的详细大小(数据+索引分开)
有时候你想知道一张表里数据占了多少,索引占了多少,方便优化。可以执行:
SELECT
table_name AS '表名',
ROUND(data_length / 1024 / 1024, 2) AS '数据大小(MB)',
ROUND(index_length / 1024 / 1024, 2) AS '索引大小(MB)',
ROUND((data_length + index_length) / 1024 / 1024, 2) AS '总大小(MB)'
FROM information_schema.tables
WHERE table_schema = 'testdb'
ORDER BY (data_length + index_length) DESC;
六、查看数据库里所有表的行数
有时候你只想知道每张表有多少行数据,不需要看大小。可以执行:
SELECT
table_name AS '表名',
table_rows AS '行数'
FROM information_schema.tables
WHERE table_schema = 'testdb'
ORDER BY table_rows DESC;
七、查看MySQL整体占了多少磁盘空间
如果你想知道整个MySQL一共占了多少磁盘空间,可以执行:
SELECT
ROUND(SUM(data_length + index_length) / 1024 / 1024 / 1024, 2) AS 'MySQL总大小(GB)'
FROM information_schema.tables;
常见坑
坑1:table_rows显示的行数不准确
很多同学发现,用 information_schema.tables 查出来的 table_rows 和实际 count(*) 出来的行数对不上。
这是因为 information_schema 里的 table_rows 是估算值,不是精确值。InnoDB引擎的话,这个值大概有10%左右的误差。如果需要精确的行数,还是得用 SELECT COUNT(*) FROM 表名。
坑2:查出来的大小和实际磁盘占用对不上
有时候你用SQL查出来的数据库大小,和用 du 命令查出来的 data 目录大小对不上,差了不少。
这是因为MySQL的data目录里除了表数据和索引,还有:
- redo log、undo log这些日志文件
- ibdata1这些系统表空间文件
- 二进制日志文件
这些都不算在表数据和索引大小里。所以用SQL查出来的大小一般会比实际磁盘占用小一点。
坑3:查完之后发现有个库特别大,不知道是什么
有时候你查完发现有个库特别大,但是你根本不知道这个库是干嘛的。一般可能是:
- mysql系统库
- information_schema、performance_schema这些系统库
- 之前测试的时候建的库,忘了删了
坑4:磁盘满了但是查出来数据库没多大
如果磁盘满了,但是查出来数据库没多大,那大概率不是数据库的问题,可能是:
- 日志文件太大(比如nginx日志、MySQL的binlog日志)
- 网站上传的文件太大
- 系统临时文件太多
这时候需要去查一下具体是哪个目录占了空间。
总结
MySQL查看数据库和表大小的常用SQL命令总结一下:
- 查看所有数据库大小:查 information_schema.tables,按 table_schema 分组
- 查看指定数据库大小:加 WHERE table_schema = '数据库名'
- 查看数据库里所有表的大小:按 table_name 分组
- 查看单张表的大小:加 AND table_name = '表名'
- 数据和索引分开看:data_length 和 index_length
- 查看行数:table_rows 字段
记住这些SQL命令,以后遇到磁盘满了的问题,就能快速定位是哪个数据库、哪张表占了空间,不用再瞎找了。
遇到问题加QQ23979811 协助处理