乐途乐途
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
    • HTTP协议
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • MyBatis
    • Spring
    • Spring MVC
    • Maven 入门
    • Maven 进阶
    • Java 设计模式
  • 缓存

    • Redis
联系
阿里云
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
    • HTTP协议
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • MyBatis
    • Spring
    • Spring MVC
    • Maven 入门
    • Maven 进阶
    • Java 设计模式
  • 缓存

    • Redis
联系
阿里云
  • 学习路径
  • 第1章 数据库基础与安装

    • MySQL 简介
    • MySQL 5.6 到 5.7 到 8.0 关键差异速查
    • 安装 MySQL 5.7
    • 连接与断开服务器
    • 创建数据库
    • 创建数据表
    • 数据库与数据表
    • 加载数据
    • 获取数据库信息
    • 批处理模式
    • SHOW 语句汇总
    • FLUSH 与 RESET 语句
    • my.cnf 核心参数
    • 字符集与排序规则
  • 第2章 SQL基础查询

    • SELECT
    • WHERE
    • ORDER BY
    • LIMIT
    • COUNT
    • 聚合函数
    • 比较运算符
    • 逻辑运算符
    • 算术运算符
    • 模式匹配
    • NULL 值处理
    • UPDATE
    • DELETE
    • REPLACE
    • SELECT INTO
  • 第3章 数据类型与运算符

    • 数值类型
    • 字符串类型
    • 日期时间类型
    • BIT 类型
    • ENUM 类型
    • SET 类型
    • JSON 类型
    • 类型转换
  • 第4章 函数与表达式

    • 字符串函数
    • 数值函数
    • 日期函数
    • 全文检索函数
  • 第5章 高级查询与子查询

    • JOIN
    • 子查询
    • UNION
    • GROUP BY
    • HAVING
    • DISTINCT
  • 第6章 表与索引

    • 数据定义语言
    • 修改表结构
    • 视图
    • 修改视图与检查选项
    • 外键
    • 索引
    • 唯一索引
    • 复合索引
    • 存储引擎对比
    • 分区表
    • 第一范式与第二范式
    • 第三范式与 BC 范式
    • 反范式设计
  • 第7章 存储过程与函数

    • 存储过程
    • 存储函数
    • 变量
    • 流程控制
    • 游标
    • 预处理语句
  • 第8章 事务与锁

    • 事务
    • 事务隔离级别
    • 锁机制
    • MVCC
    • 死锁专题分析
    • LOCK TABLES
    • XA 事务
  • 第9章 用户管理与安全

    • 用户管理
    • 权限管理
    • 角色
    • SQL 注入防范
  • 第10章 性能优化入门

    • 执行计划
    • 索引优化
    • 查询优化
    • 查询优化器提示
    • 慢查询日志
    • InnoDB 深入机制
    • InnoDB 专项优化
    • Performance Schema
    • sys Schema
  • 第11章 复制与高可用

    • 主从复制原理
    • 半同步复制配置
    • binlog 开启与 point-in-time 恢复
    • mysqldump 全库备份
    • mysqldump 单表与条件备份
    • mysqldump 恢复与导入
    • xtrabackup 全量热备
    • xtrabackup 准备与恢复
    • xtrabackup 增量与流式备份
  • 第12章 触发器与事件

    • 触发器
    • 事件调度器
  • 参考

    • MySQL 5.7 专业术语大全
    • MySQL 5.7 关键字与保留字大全

sys Schema

导学

Performance Schema 的数据非常底层,要找出"哪些 SQL 最慢""哪些表最热门""哪些索引没用到",需要写复杂的聚合 SQL。sys Schema 是 MySQL 5.7 内置的一套视图和存储过程,它把 Performance Schema 和 information_schema 的原始数据加工成人类可读的性能诊断报告。一条简单的 SELECT * FROM sys.session 就能看到当前所有连接的详细状态。

定义

sys Schema:MySQL 5.7 内置的数据库(默认安装),包含基于 Performance Schema 和 information_schema 构建的视图、存储过程和函数。它将底层性能数据汇总为直观的诊断报告,大幅降低性能分析门槛。

核心视图分类

视图前缀用途示例
sys.session / sys.processlist当前连接和会话状态替代 SHOW PROCESSLIST,信息更丰富
sys.statement_analysisSQL 语句性能分析最慢的 SQL、全表扫描的 SQL
sys.schema_table_statistics表级 I/O 和锁统计最热门的表、读写最多的表
sys.schema_index_statistics索引使用统计哪些索引被用到、哪些索引是冗余的
sys.schema_unused_indexes从未使用的索引清理冗余索引的依据
sys.innodb_buffer_stats_by_tableInnoDB 缓冲池统计哪些表占用了最多的缓冲池
sys.host_summary按客户端主机汇总哪个应用服务器连接最多

SQL 示例

场景一:查看当前连接(替代 SHOW PROCESSLIST)

执行语句:

-- 查看当前所有连接(比 SHOW PROCESSLIST 信息更丰富)
SELECT 
    thd_id,
    conn_id,
    user,
    db,
    command,
    state,
    time,
    current_statement,
    execution_engine,
    rows_examined,
    rows_sent,
    created_tmp_tables,
    created_tmp_disk_tables
FROM sys.session
WHERE conn_id IS NOT NULL
ORDER BY time DESC;

操作后结果(示例):

thd_idconn_iduserdbcommandstatetimecurrent_statementrows_examinedrows_sent
255root@localhostcompanyQuerySending data12SELECT * FROM employees WHERE ...10000002
266app@192.168.1.5companySleep120NULL00

结果解读:

  • sys.session 整合了 performance_schema.threads 和 performance_schema.events_statements_current 的数据
  • 比 SHOW PROCESSLIST 多了 rows_examined(扫描行数)、rows_sent(返回行数)、临时表统计等关键指标
  • time 是当前状态持续时间(秒),值很大且 state = 'Sending data' 或 'Locked' 需要关注
  • current_statement = NULL 表示连接空闲(command = 'Sleep')

场景二:找出最慢的 SQL 语句

执行语句:

-- 查看执行时间最长的 SQL(全表扫描、临时表、排序等一目了然)
SELECT 
    query,
    db,
    exec_count,
    total_latency,
    avg_latency,
    rows_sent_avg,
    rows_examined_avg,
    full_scans,
    tmp_tables,
    tmp_disk_tables,
    last_seen
FROM sys.statement_analysis
ORDER BY total_latency DESC
LIMIT 10;

操作后结果(示例):

querydbexec_counttotal_latencyavg_latencyrows_examined_avgfull_scanstmp_tables
SELECT * FROM employees WHERE ...company15045.23 s301.5 ms5000001500
SELECT COUNT(*) FROM orders ...company100012.10 s12.1 ms1000010000

结果解读:

  • sys.statement_analysis 汇总了 events_statements_summary_by_digest 的数据
  • total_latency 是累计执行时间,avg_latency 是平均每次执行时间
  • rows_examined_avg 平均每次扫描行数,远大于 rows_sent_avg 说明需要优化索引
  • full_scans 是全表扫描次数,值高说明没有用到索引或索引选择不当
  • tmp_tables / tmp_disk_tables 是创建临时表的次数,磁盘临时表尤其需要关注

场景三:找出最热门的表

执行语句:

-- 查看各表的 I/O 统计(读、写、延迟)
SELECT 
    table_schema,
    table_name,
    rows_fetched,
    fetch_latency,
    rows_inserted,
    insert_latency,
    rows_updated,
    update_latency,
    rows_deleted,
    delete_latency,
    io_read_requests,
    io_write_requests
FROM sys.schema_table_statistics
ORDER BY fetch_latency DESC
LIMIT 10;

操作后结果(示例):

table_schematable_namerows_fetchedfetch_latencyrows_insertedinsert_latencyio_read_requests
companyemployees15000012.5 s5000.5 s3000
companyorders500008.3 s20001.2 s1500

结果解读:

  • sys.schema_table_statistics 按表汇总了读写次数和 I/O 延迟
  • fetch_latency 是读取累计耗时,insert_latency / update_latency / delete_latency 是写入耗时
  • io_read_requests / io_write_requests 是底层 I/O 请求次数
  • 结合 rows_fetched 和 fetch_latency 可以判断:是访问量大(正常)还是单次读取慢(需要优化)

场景四:找出从未使用的索引(清理冗余索引)

执行语句:

-- 查看哪些索引从未被使用(清理候选)
SELECT 
    object_schema,
    object_name,
    index_name
FROM sys.schema_unused_indexes
ORDER BY object_schema, object_name;

操作后结果(示例):

object_schemaobject_nameindex_name
companyemployeesidx_old_name
companyordersidx_temp_field

结果解读:

  • sys.schema_unused_indexes 对比 information_schema.STATISTICS(有哪些索引)和 performance_schema.table_io_waits_summary_by_index_usage(哪些索引被用到)
  • 列出的索引自服务器启动以来从未被查询使用
  • 清理这些索引可以减少写入开销(每次写入都要维护索引)和磁盘空间
  • 注意:某些索引可能只在月度报表中使用,需要结合业务周期判断,不要仅凭短期数据删除

场景五:查看 InnoDB 缓冲池中的热点表

执行语句:

-- 查看哪些表占用了最多的 InnoDB 缓冲池空间
SELECT 
    object_schema,
    object_name,
    allocated,
    data,
    pages,
    pages_hashed,
    pages_old,
    rows_cached
FROM sys.innodb_buffer_stats_by_table
ORDER BY allocated DESC
LIMIT 10;

操作后结果(示例):

object_schemaobject_nameallocateddatapagesrows_cached
companyemployees256.00 MiB180.00 MiB16384500000
companyorders128.00 MiB90.00 MiB8192200000

结果解读:

  • sys.innodb_buffer_stats_by_table 按表统计 InnoDB 缓冲池中的页占用情况
  • allocated 是缓冲池中为该表分配的总空间(包括索引页和数据页)
  • pages 是占用的页数(每页 16KB),pages_hashed 是自适应哈希索引中的页数
  • 如果某表 allocated 很大但业务上不是热点表,说明可能有全表扫描把它刷进了缓冲池,挤占了其他热数据

场景六:生成诊断报告(存储过程)

执行语句:

-- 生成指定时间段的诊断报告(需要 SUPER 权限)
CALL sys.diagnostics(60, 30, 'current');

参数说明:

参数含义
in_interval (60)采样间隔秒数
in_average (30)平均计算窗口秒数
in_auto_config ('current')自动配置模式:'current' 使用当前配置,'medium'/'full' 自动开启更多 instruments

结果解读:

  • sys.diagnostics() 存储过程会自动采集 Performance Schema 数据,生成包含以下内容的报告:
    • 当前连接状态
    • 最慢的 SQL
    • 最热门的表和索引
    • InnoDB 事务和锁状态
    • 内存使用统计
  • 适合在性能问题发生时快速采集现场数据,比手动写 SQL 高效得多
  • 输出是文本格式,可以直接复制到性能分析报告中

常见误区

误区正解
"sys Schema 需要单独安装"不需要。MySQL 5.7 默认安装并启用,数据库列表中可以看到 sys 库。
"sys Schema 的数据是实时的"是实时的(基于 Performance Schema 内存数据),但某些视图是汇总的(如 statement_analysis 是历史累计)。重启后 Performance Schema 数据清空,sys 视图也相应清空。
"schema_unused_indexes 可以无脑删索引"不能。某些索引可能只在月度/季度报表中使用,或只在特定业务场景使用。删除前应确认业务周期,并先在测试环境验证。
"sys Schema 会拖慢数据库"不会。sys Schema 只是视图和存储过程,查询时实时从 Performance Schema 和 information_schema 聚合数据,本身不存储数据,也不产生额外监控开销。
"sys Schema 可以替代所有性能监控工具"不能。sys Schema 适合临时诊断和开发测试环境;生产环境持续监控应配合 Prometheus + mysqld_exporter、PMM 等专业工具。
"sys.session 和 SHOW PROCESSLIST 完全一样"不是。sys.session 信息更丰富(rows_examined、临时表、执行引擎等),且基于 Performance Schema,不依赖 PROCESS 权限(但查询 sys 视图需要相应权限)。

面试考点

Q:sys Schema 和 Performance Schema 的关系?

sys Schema 是基于 Performance Schema 和 information_schema 构建的视图层。Performance Schema 提供底层原始事件数据(如每个语句的耗时、扫描行数),sys Schema 将这些数据汇总加工成人类可读的诊断报告(如最慢 SQL、未使用索引、热点表)。两者关系类似"数据仓库的原始表 vs 报表视图"。

Q:如何找出数据库中冗余的索引?

查询 sys.schema_unused_indexes,它列出了自服务器启动以来从未被使用过的索引。但删除前应确认:1. 业务是否有周期性查询(如月度报表)用到该索引;2. 该索引是否是唯一约束(唯一索引即使不用于查询也有数据完整性作用);3. 在测试环境验证删除后的性能影响。

Q:sys.statement_analysis 中的 full_scans 高说明什么?

说明该 SQL 执行了全表扫描(或全索引扫描),没有有效利用索引。可能原因:1. WHERE 条件没有索引;2. 索引选择性差(如性别字段);3. 数据量小,优化器认为全表扫描更快;4. 查询条件使用了函数或类型转换,导致索引失效。

Q:sys Schema 在生产环境怎么用?

  1. 问题发生时快速诊断:SELECT * FROM sys.session WHERE command != 'Sleep' ORDER BY time DESC 看当前慢连接;2. 定期巡检:SELECT * FROM sys.statement_analysis ORDER BY total_latency DESC LIMIT 20 找慢 SQL;3. 索引优化:SELECT * FROM sys.schema_unused_indexes 找冗余索引;4. 配合 sys.diagnostics() 生成诊断报告。注意:sys 数据重启后清空,持续监控需要外部工具。

Q:sys.session 中的 rows_examined 和慢查询日志的 Rows_examined 有什么区别?

本质来源相同(都来自 Performance Schema),但 sys.session 是实时当前值(events_statements_current),慢查询日志是语句执行完成后的最终值。sys.session 可以在语句执行过程中观察进度,慢查询日志只能事后分析。

小结

  • sys Schema 是 MySQL 5.7 内置的诊断视图库,基于 Performance Schema 和 information_schema 构建
  • sys.session 替代 SHOW PROCESSLIST,信息更丰富(扫描行数、临时表等)
  • sys.statement_analysis 汇总慢 SQL,关注 full_scans、tmp_disk_tables、rows_examined_avg
  • sys.schema_unused_indexes 找出从未使用的索引,是清理冗余索引的依据
  • sys.innodb_buffer_stats_by_table 看缓冲池热点,判断是否有冷数据挤占热数据
  • sys.diagnostics() 存储过程可一键生成综合诊断报告
  • sys Schema 只是视图层,不存储数据,查询开销低,适合临时诊断

下一章引子:sys Schema 让我们看清了"哪里慢",但有时候优化器没有选择最优的执行计划——比如明明有合适的索引却走了全表扫描。Optimizer Hints 和 Index Hints 让你能手动干预优化器的决策。

上一页
Performance Schema