
接手一台新数据库环境或者刚入门 MySQL 的时候大家问得最多的往往不是“怎么写复杂 SQL”也不是“怎么做主从”而是最朴素的一句mysql 怎么查看。就我这些年帮同事救火、带新人、自己也踩过不少坑的体会来说这个“查看”涵盖的东西比想象中多得多——你能查到数据库列表、表结构、索引、权限、连接数、锁等待、慢日志甚至能通过几张系统表把一台实例的家底摸得清清楚楚。很多时候排查问题卡壳不是 MySQL 不行而是你根本不知道“原来还能这样看”。所以这篇文章我想把它一次性讲透。内容不追求面面俱到但凡是日常运维和开发里高频用到的“查看”手段我都会把命令、输出解读、使用场景和个人经验放在一起说。你可以把它当成一篇备忘文档也可以跟着顺序实操一遍只要能帮你少走一点弯路这文章就没白写。1. 先搞清楚你要“查看”什么四类高频需求MySQL 的“查看”不像开一个软件看界面那么直接它更像你在命令行里跟数据库对话。要对话就得先知道对方手里有哪些“抽屉”。我通常把日常的查看需求分成四类这样排查问题的时候思路会清楚得多。1.1 一条命令走遍全局SHOW 与 SELECT 的边界很多人第一次接触 MySQL 查看功能时会被SHOW和SELECT搞得有点晕。其实理解起来很简单SHOW是 MySQL 提供的一批“快捷查看指令”专门用来查看数据库自身的元数据信息比如有哪些库、哪些表、表结构是什么样而SELECT是标准的查询语句主要用来查表里的业务数据也能查一些系统视图。举个例子你想知道当前实例有哪些数据库用SHOW DATABASES;一条命令就能搞定但如果你想知道这些数据库各自占了多少磁盘空间就得用SELECT去查information_schema这个系统库里的表。这两种方式没有谁更高级关键看你要拿什么信息。我个人的习惯是能通过SHOW快速解决的就用SHOW拿不到或者需要汇总统计的再去查information_schema。这个习惯在应对面试题和线上问题时都很实用。1.2 高频需求分类库、表、结构、数据、状态把需求分类之后你就能对号入座库层面查看实例上有哪些数据库、每个库的字符集是什么、库的大小。表层面某个库里有几张表、表的行数大概多少、表的存储引擎。结构层面表的字段定义、索引、主键、自增值、外键。数据层面表里的实际业务数据按条件筛选、排序、分页。状态层面当前连接数、线程运行情况、锁等待、慢查询、系统变量配置。这篇文章后面的内容基本就是按照这个分类展开。你不需要一次全记住但建议把命令收藏起来真到用时能快速找到比临阵乱试高效得多。2. 从零开始看库看表看结构命令行操作实录这一节是纯实操我会模拟一个新接手环境的场景带着你一步步敲命令、看输出。2.1 连接实例后第一步——查看数据库列表登录 MySQL 之后第一件事通常是确认自己在哪台实例上、能看到哪些库mysql -uroot -p然后执行SHOW DATABASES;输出大致长这样-------------------- | Database | -------------------- | information_schema | | mysql | | performance_schema | | sys | | my_app | | my_blog | --------------------这里要注意information_schema、mysql、performance_schema、sys这几个是系统自带的库平时不要轻易动它们。真正需要关注的是像my_app、my_blog这样的业务库。如果你接手的是一台老环境库很多还可以加模糊过滤。MySQL 的SHOW命令支持LIKE语法SHOW DATABASES LIKE my%;这个技巧在库特别多的时候很有用一眼就能筛出自己关心的那批库。我第一次接手公司老项目时实例上有两百多个库全靠这条命令快速定位。2.2 进入一个库之后——查看所有表和表结构知道有哪些库之后下一步就是进入目标库看里面有哪些表USE my_app; SHOW TABLES;如果想看表结构有三种常用方式。第一种是DESC命令最直观DESC users;输出会列出字段名、类型、是否允许为空、键信息、默认值等是平时看得最多的。第二种是查看建表语句信息更完整连字符集、注释、索引都能看到SHOW CREATE TABLE users\G这里用\G代替分号结尾输出会从横排变成竖排列多的时候比横排清晰很多。第三种是直接查系统视图information_schema.columns适合批量导出字段信息或者写脚本用后面会专门讲。2.3 查看建表语句和字符集信息很多人忽略字符集但它恰恰是乱码问题的根源。想看某个库的默认字符集SHOW CREATE DATABASE my_app;想看某张表的字符集直接看SHOW CREATE TABLE users\G输出里的DEFAULT CHARSET部分即可。我在实际环境里见过不少因表字符集不一致导致的乱码事故应用连接的字符集是 utf8mb4表是 latin1查出来中文全是问号。所以接手的第一个小时建议把每个业务库的字符集都过一遍确认是 utf8mb4。库统一、表统一、连接也统一乱码问题能少一大半。3. 查看表里的数据是有讲究的普通查询和定位查询库和表的结构都清楚了接下来才是真正高频的“看数据”。这部分不仅要知道SELECT * FROM xx更要懂得怎么高效、安全地看。3.1 SELECT 的基本姿势与分页、条件查询最基本的查看SELECT * FROM users;这在开发环境没问题但在生产环境数据量一大就直接“炸”——全表扫描会把数据库 IO 拉满。正确的姿势是按需取列、加过滤条件SELECT id, username, created_at FROM users WHERE status 1 ORDER BY id DESC LIMIT 100;这里几个关键点MySQL 没有像 Oracle 那样的ROWNUM概念也没有TOP分页用LIMIT offset, count。但 offset 越大翻页越慢。比如LIMIT 100000, 20MySQL 依然会先扫出前 100020 条再丢弃前 100000 条。大数据量下的深度分页更推荐“键位分页”也就是记住上一页最后一条记录的 id然后用WHERE id ?配合LIMITSELECT id, username, created_at FROM users WHERE status 1 AND id 200000 ORDER BY id ASC LIMIT 20;这种方式在千万级表里翻页性能稳定得多。我帮同事优化过一个后台列表就是把 offset 分页改成键位分页查询耗时从三四秒降到几十毫秒。3.2 用 EXPLAIN 查看一条 SQL 的执行计划“查看一条 SQL 到底怎么执行的”是最容易被忽略、却最影响性能的能力。用法是在 SELECT 前面加EXPLAINEXPLAIN SELECT id, username FROM users WHERE status 1 ORDER BY created_at DESC LIMIT 100;输出里的type字段是重中之重。ALL代表全表扫描index代表全索引扫描ref、eq_ref、const代表走了索引且效果很好。还有一个Extra字段如果出现Using filesort或Using temporary说明排序或分组没走好索引数据量一大就会慢。线上排查慢 SQL 的时候我的固定动作是先把目标 SQL 拿出来EXPLAIN一遍看 type 和 key如果 type 是 ALL第一反应就是看 where 条件里的字段有没有建索引。很多时候问题就出在这一步。3.3 查看字段注释、自增值、行数估算等元数据字段注释这种东西在别人维护的老表里特别重要。没有注释的字段读起来全靠猜。查看方式SELECT COLUMN_NAME, COLUMN_TYPE, IS_NULLABLE, COLUMN_DEFAULT, COLUMN_COMMENT FROM information_schema.COLUMNS WHERE TABLE_SCHEMA my_app AND TABLE_NAME users;想看某张表的自增值当前值SHOW TABLE STATUS FROM my_app LIKE users\G输出里有Auto_increment字段能直接看到下一个自增 ID 是多少。这在排查“为什么新增的数据 ID 跳了好大一截”时特别有效。需要说明的是MySQL 8.0 之后自增值不再持久化到磁盘重启后继续读auto_increment缓存值所以数据量大的表可能需要你关注一下。行数也是从这里看SHOW TABLE STATUS里的Rows字段。但它对 InnoDB 来说是个估算值不是精确值千万别拿它当准确行数用。要精确行数只能COUNT(*)但大表COUNT(*)很慢这就是另一个话题了。4. 索引这类“看不见的东西”怎么查索引是性能的核心但它是“看不见的东西”必须通过命令才能看到全貌。4.1 SHOW INDEX FROM 查看索引详情SHOW INDEX FROM users;输出里每一行代表索引中的一个字段。重点看这几个列Key_name索引名字。主键索引通常叫 PRIMARY。Seq_in_index字段在索引中的顺序联合索引靠这个看出先后关系。Column_name索引的字段名。Non_unique0 表示唯一索引1 表示非唯一。Cardinality索引基数估算值。它表示索引列有多少个不同的值如果相对行数很小说明这个索引区分度很差实际效果可能不好。这里我特别想提醒的一点SHOW INDEX只能看到索引定义看不出它到底有没有被用上。要判断一个索引是否生效必须回到EXPLAIN看执行计划里的key字段是否真的用了它。4.2 通过 statistics 表和生产日志判断索引是否生效除了SHOW INDEXinformation_schema.statistics表也包含了同样的索引信息。两者的区别是前者人性化适合人看后者适合写 SQL 做批量统计。比如你想找出某个库里所有建在重复字段上的冗余索引逻辑就很好写的。实际生产里判断索引是否真的被用到我养成了一个习惯开启慢查询日志和log_queries_not_using_indexes参数然后定期看慢日志里的记录。如果一条 SQL 频繁出现在慢日志里但EXPLAIN显示它没走任何索引那就基本可以确定索引设计有问题。补上合适的索引之后再观察慢日志是否还有这条记录这样验证索引是否生效是最直接的。5. 数据库的“体检数据”怎么查容量、状态、连接业务跑得稳不稳很多时候要看“体检数据”。这一节里的命令每一个都是排查故障时的“杀手锏”。5.1 查看各库各表占用空间磁盘满了、慢查询变多第一时间要查哪些库哪些表是“空间大户”。直接执行SELECT TABLE_SCHEMA, TABLE_NAME, ROUND((DATA_LENGTH INDEX_LENGTH) / 1024 / 1024, 2) AS size_mb FROM information_schema.TABLES WHERE TABLE_SCHEMA NOT IN (mysql, information_schema, performance_schema, sys) ORDER BY size_mb DESC LIMIT 20;这条 SQL 能把占用空间最大的前 20 张表列出来非常直观。按库汇总也一样简单把TABLE_SCHEMA提到最前面对size_mb做SUM就行。我在清理磁盘的时候靠这个看了不知道多少次每次都能快速定位到哪几张表占了空间。5.2 查看当前连接、线程和锁等待数据库连不上或者卡住第一件事就是看当前连接数SHOW STATUS LIKE Threads_connected; SHOW PROCESSLIST;SHOW PROCESSLIST的输出里State字段很关键。如果看到一堆Waiting for table metadata lock说明有人持有 MDL 锁不释放后面的查询全部排队如果看到Updating/Sending data状态很多那多半是慢 SQL 在刷屏。MySQL 8.0 里是INFORMATION_SCHEMA.PROCESSLIST作用和SHOW PROCESSLIST一致。如果某条连接出问题可以在SHOW PROCESSLIST拿到Id后用KILL id把它干掉。不过这条命令要慎用kill 错连接会导致正在执行的事务回滚影响业务。锁等待的另一个高发场景是行锁冲突。想查看当前有没有锁等待SELECT * FROM performance_schema.data_lock_waits;这个视图在 MySQL 8.0 和 5.7 里都存在能看到锁和锁之间的等待关系。输出的结果比较复杂第一次看可能有点懵但至少可以帮你确认“有没有锁、谁在等谁”。真到了要分析死锁的时候更常用的还是SHOW ENGINE INNODB STATUS\G里的事务部分配合SHOW PROCESSLIST一起看。5.3 查看系统变量和运行状态全局配置对不对靠SHOW VARIABLES看SHOW VARIABLES LIKE max_connections; SHOW VARIABLES LIKE innodb_buffer_pool_size;运行状态则靠SHOW STATUSSHOW STATUS LIKE Uptime; SHOW GLOBAL STATUS LIKE Threads_connected;这几个命令在判断“为什么连接数满了”“缓冲池是不是太小”时特别关键。比如max_connections默认只有 151稍微大点的业务就很容易打满innodb_buffer_pool_size如果设得太小大量热点数据没法缓存在内存里查询就会频繁走磁盘性能会差非常多。6. 权限与用户信息查看别漏掉排查问题的时候我经常遇到“用户查不了某张表”“某个账号是不是权限太大了”这种诉求。这类问题同样属于“查看”的范畴。6.1 查看用户列表和权限查看实例上有哪些用户SELECT user, host FROM mysql.user;注意 MySQL 的账号是由user host共同组成的同一个用户名配不同的 host 其实是两个账号。appuser%和appuserlocalhost看起来像同一个实际是两条独立的记录权限也互不影响。这个细节在处理授权问题时特别容易踩坑。查看某个账号的权限SHOW GRANTS FOR appuser%;输出会是好几条GRANT ... ON ... TO ...语句一眼就能看到这个账号能操作哪些库、哪些权限。如果只想看某个库的权限还可以在SHOW GRANTS后加数据库名过滤。6.2 常用权限字段解析权限输出里SELECT、INSERT、UPDATE、DELETE这些是 DML 权限CREATE、ALTER、DROP、INDEX是 DDL 权限GRANT OPTION表示这个账号可以给其他账号授权属于高危权限。ALL PRIVILEGES就是除了GRANT OPTION之外的全部权限一般只建议给管理员账号用。我给业务账号的授权原则是能不给 DROP 就不给 DROP能不给 GRANT OPTION 就不给 GRANT OPTION。权限最小化在出事故的时候能救命这句话不是开玩笑的。7. 结合真实场景看懂这些“查看”怎么组合单独的命令好记难的是组合。我拿三个最常见的场景把上面的命令串起来演示一遍。7.1 场景一新接手环境快速摸清家底接到一台从没见过的实例我的节奏是先SHOW DATABASES;看有哪些库。对每个业务库SHOW TABLES;看表清单。抽查核心表的SHOW CREATE TABLE确认引擎、字符集、索引。跑一遍空间占用排名 SQL知道最大的几张表是谁。SHOW PROCESSLIST;看一眼当前有没有诡异连接。最后SHOW VARIABLES LIKE max_connections和innodb_buffer_pool_size确认配置是否在合理范围。这一套走下来一台陌生实例的大致脾气基本就摸清了。很多同事问我“你接手的项目怎么上手这么快”其实不是天赋就是这套流程熟而已。7.2 场景二线上一条慢 SQL怎么一步步查看有业务反馈某个页面转圈圈手里只有一条慢 SQL。我的排查链路是这样的先EXPLAIN这条 SQL看type和key判断有没有走索引。如果走了索引还是慢看Extra有没有Using filesort/Using temporary有的话大概率是排序或者分组字段没在索引里。SHOW INDEX FROM 对应表看索引定义确认有没有联合索引能覆盖排序字段。如果数据量大且筛选条件区分度低比如status 1只能过滤掉 1% 的数据索引效果也不会好可能得改写 SQL 或用其他方案。这套链路走下来90% 的慢 SQL 都能定位到根因。7.3 场景三字段乱码如何从底层查看确认字符集乱码问题很高频。我的查看顺序是SHOW CREATE TABLE xxx;看表字符集。SHOW VARIABLES LIKE character_set%;看客户端、连接、服务端的字符集设置。确认三者的值是否统一为标准建议值utf8mb4和utf8mb4_unicode_ci或utf8mb4_0900_ai_ciMySQL 8.0 默认。如果表和连接都是 utf8mb4 但历史数据已经乱码那就得用ALTER TABLE转换字符集或者从源头修复数据。乱码问题九成以上出在“连接字符集”和“表字符集”不一致很多人只改表不改连接结果怎么折腾都没用。写在最后的几点经验MySQL 的“查看”不是一条命令走天下而是围绕SHOW、DESC、information_schema、performance_schema、SHOW PROCESSLIST这些工具展开的组合拳。我个人习惯是把这些命令整理成一段段 SQL 脚本存成.sql文件放在本地的~/.mysql/目录里遇到新环境直接执行输出一目了然。这套方法陪了我很多年效率确实高。如果你看完这篇文章只记住三件事我希望是第一查看表结构用DESC和SHOW CREATE TABLE前者看字段后者看全貌第二排查性能问题先EXPLAIN再SHOW INDEX顺序不能乱第三遇到任何“数据库怎么查看”的疑问优先查information_schema和performance_schema它们才是 MySQL 的“数据库的数据库”。最后再分享一个小技巧每次你因为某个查看命令找不到而烦躁的时候把它顺手记进自己的备忘录里攒多了你会发现很多“不会看”的问题其实是“没查过文档”。时间长了这些命令就会像肌肉记忆一样帮你更快地定位问题、解决问题。