Skip to content

TDSQL 性能瓶颈分析

性能数据收集

系统资源数据

CPU数据

bash
# 查看CPU使用率
top

# 查看CPU详细信息
mpstat -P ALL 1

# 查看进程CPU使用情况
pidstat -p $(pgrep mysqld) 1

内存数据

bash
# 查看内存使用情况
free -h

# 查看进程内存使用情况
pmap -x $(pgrep mysqld)

# 查看内存使用详情
pidstat -r -p $(pgrep mysqld) 1

磁盘IO数据

bash
# 查看磁盘使用率
df -h

# 查看磁盘IO情况
iostat -x 1

# 查看进程IO情况
pidstat -d -p $(pgrep mysqld) 1

# 查看详细IO统计
iotop

网络数据

bash
# 查看网络连接情况
netstat -tuln

# 查看网络流量
tcpdump -i eth0 -nn port 3306

# 查看进程网络使用情况
pidstat -p $(pgrep mysqld) -s 1

数据库性能数据

状态数据

sql
-- 查看全局状态
SHOW GLOBAL STATUS;

-- 查看会话状态
SHOW SESSION STATUS;

-- 查看InnoDB状态
SHOW ENGINE INNODB STATUS\G

慢查询日志

ini
# 启用慢查询日志
slow_query_log = 1
slow_query_log_file = /var/log/tdsql/slow.log
long_query_time = 1
log_queries_not_using_indexes = 1

Performance Schema

sql
-- 启用Performance Schema
UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME LIKE 'statement%';

-- 查看语句执行统计
SELECT * FROM performance_schema.events_statements_summary_by_digest ORDER BY SUM_TIMER_WAIT DESC LIMIT 10;

线程状态

sql
-- 查看当前线程状态
SHOW PROCESSLIST;

-- 查看线程详细信息
SHOW FULL PROCESSLIST;

-- 查看线程等待情况
SELECT * FROM performance_schema.threads WHERE PROCESSLIST_ID = <thread_id>\G

性能瓶颈类型

1. CPU瓶颈

表现特征

  • CPU使用率持续高于90%
  • 系统负载过高
  • 上下文切换频繁
  • 响应时间延长

常见原因

  • 大量复杂查询
  • 缺少索引导致全表扫描
  • 排序和分组操作过多
  • 连接数过多
  • 存储引擎配置不当

分析方法

sql
-- 查看占用CPU高的查询
SELECT * FROM performance_schema.events_statements_summary_by_digest WHERE SUM_TIMER_WAIT > 1000000000000 ORDER BY SUM_TIMER_WAIT DESC LIMIT 10;

-- 查看当前运行的查询
SHOW FULL PROCESSLIST WHERE Command != 'Sleep';

2. 内存瓶颈

表现特征

  • 内存使用率持续高于90%
  • 频繁的页面交换
  • 缓存命中率下降
  • 响应时间延长

常见原因

  • 缓冲池配置过小
  • 查询缓存配置不当
  • 内存泄漏
  • 连接数过多
  • 临时表使用过多

分析方法

sql
-- 查看缓冲池使用情况
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool%';

-- 查看缓冲池命中率
SELECT (1 - (@@Innodb_buffer_pool_reads / @@Innodb_buffer_pool_read_requests)) * 100 AS buffer_pool_hit_rate;

-- 查看临时表使用情况
SHOW GLOBAL STATUS LIKE 'Created_tmp%';

3. 磁盘IO瓶颈

表现特征

  • 磁盘IO使用率持续高于80%
  • 磁盘等待时间过长
  • IO队列长度过大
  • 响应时间延长

常见原因

  • 大量随机IO操作
  • 缺少索引导致全表扫描
  • 日志刷盘策略不当
  • 磁盘空间不足
  • 存储设备性能不足

分析方法

sql
-- 查看IO相关状态
SHOW GLOBAL STATUS LIKE 'Innodb_data%';
SHOW GLOBAL STATUS LIKE 'Innodb_log%';

-- 查看表空间使用情况
SELECT table_schema, table_name, data_length, index_length, data_free FROM information_schema.tables WHERE table_schema NOT IN ('information_schema', 'mysql', 'performance_schema') ORDER BY (data_length + index_length) DESC LIMIT 10;

4. 网络瓶颈

表现特征

  • 网络流量持续接近带宽上限
  • 连接延迟增加
  • 连接超时频繁
  • 响应时间延长

常见原因

  • 大量数据传输
  • 连接数过多
  • 网络设备性能不足
  • 网络配置不当

分析方法

sql
-- 查看连接数
SHOW GLOBAL STATUS LIKE 'Threads_connected';

-- 查看网络相关状态
SHOW GLOBAL STATUS LIKE 'Bytes%';
SHOW GLOBAL STATUS LIKE 'Connections';

5. 应用层瓶颈

表现特征

  • 大量慢查询
  • 连接池配置不当
  • 事务处理不当
  • 应用逻辑问题

常见原因

  • SQL查询优化不当
  • 缺少索引
  • 长事务
  • 连接泄漏
  • 应用架构问题

分析方法

sql
-- 查看慢查询
SELECT * FROM mysql.slow_log ORDER BY start_time DESC LIMIT 10;

-- 查看未使用索引的查询
EXPLAIN SELECT * FROM your_table WHERE condition;

性能瓶颈定位工具

1. 内置工具

EXPLAIN

sql
-- 分析查询执行计划
EXPLAIN SELECT * FROM orders WHERE user_id = 123 AND created_at > '2023-01-01';

-- 分析更新语句
EXPLAIN UPDATE orders SET status = 2 WHERE id = 1;

SHOW PROFILE

sql
-- 启用 profiling
SET profiling = 1;

-- 执行查询
SELECT * FROM orders WHERE user_id = 123;

-- 查看查询 profile
SHOW PROFILES;

-- 查看详细 profile
SHOW PROFILE FOR QUERY 1;

Performance Schema

sql
-- 查看语句执行统计
SELECT DIGEST_TEXT, COUNT_STAR, SUM_TIMER_WAIT, AVG_TIMER_WAIT 
FROM performance_schema.events_statements_summary_by_digest 
ORDER BY SUM_TIMER_WAIT DESC LIMIT 10;

-- 查看索引使用情况
SELECT * FROM performance_schema.table_io_waits_summary_by_index_usage 
WHERE OBJECT_SCHEMA = 'your_database' ORDER BY COUNT_STAR DESC LIMIT 10;

2. 第三方工具

Percona Toolkit

bash
# 分析慢查询日志
pt-query-digest /var/log/tdsql/slow.log

# 分析索引使用情况
pt-index-usage /var/log/tdsql/slow.log

# 检查表和索引
pt-table-checksum

MySQL Workbench

  • 提供可视化的性能监控
  • 支持查询分析和优化建议
  • 提供性能报告生成功能

Prometheus + Grafana

  • 实时监控系统和数据库性能
  • 提供丰富的可视化图表
  • 支持告警和通知

性能优化策略

1. 索引优化

sql
-- 添加缺失索引
ALTER TABLE orders ADD INDEX idx_user_id_created_at (user_id, created_at);

-- 删除冗余索引
DROP INDEX idx_old_index ON orders;

-- 优化索引结构
ALTER TABLE orders ADD INDEX idx_cover (order_no, status, amount) INVISIBLE;

2. 查询优化

sql
-- 优化前
SELECT * FROM orders WHERE DATE(created_at) = '2023-01-01';

-- 优化后
SELECT * FROM orders WHERE created_at >= '2023-01-01' AND created_at < '2023-01-02';

-- 优化前
SELECT COUNT(*) FROM orders GROUP BY status;

-- 优化后
SELECT status, COUNT(*) FROM orders GROUP BY status WITH ROLLUP;

3. 配置优化

ini
# 优化InnoDB缓冲池
innodb_buffer_pool_size = 256G
innodb_buffer_pool_instances = 16

# 优化日志配置
innodb_log_file_size = 2G
innodb_log_files_in_group = 4
innodb_flush_log_at_trx_commit = 2

# 优化连接配置
max_connections = 4096
wait_timeout = 300

4. 架构优化

  • 实现读写分离
  • 进行分库分表
  • 引入缓存机制
  • 优化存储结构

最佳实践

1. 定期性能分析

  • 每周进行一次全面性能分析
  • 监控关键性能指标趋势
  • 建立性能基线

2. 实时监控

  • 配置性能监控工具
  • 设置合理的告警阈值
  • 及时处理性能异常

3. 预防性优化

  • 定期优化索引
  • 优化查询语句
  • 调整配置参数
  • 升级硬件资源

4. 持续优化

  • 跟踪优化效果
  • 记录优化历史
  • 分享优化经验

常见问题(FAQ)

Q1: 如何快速定位性能瓶颈?

A1: 快速定位性能瓶颈的步骤:

  1. 检查系统资源使用率(CPU、内存、IO、网络)
  2. 查看慢查询日志
  3. 分析查询执行计划
  4. 检查线程状态
  5. 查看InnoDB状态
  6. 使用Performance Schema分析

Q2: 如何区分CPU瓶颈和IO瓶颈?

A2: 区分CPU和IO瓶颈的方法:

  • CPU瓶颈:CPU使用率高,IO使用率相对较低
  • IO瓶颈:IO使用率高,CPU使用率相对较低
  • 可以使用iostat和top命令同时查看

Q3: 如何处理大量慢查询?

A3: 处理大量慢查询的方法:

  1. 分析慢查询日志,找出最频繁的慢查询
  2. 为查询添加合适的索引
  3. 优化查询语句结构
  4. 考虑使用缓存
  5. 调整数据库配置

Q4: 如何优化InnoDB性能?

A4: InnoDB性能优化建议:

  1. 合理设置缓冲池大小
  2. 优化日志配置
  3. 调整IO相关参数
  4. 优化索引设计
  5. 调整事务隔离级别

Q5: 如何监控数据库性能?

A5: 监控数据库性能的方法:

  1. 使用内置状态变量
  2. 启用慢查询日志
  3. 配置Performance Schema
  4. 使用第三方监控工具
  5. 定期生成性能报告

Q6: 性能优化后如何验证效果?

A6: 验证性能优化效果的方法:

  1. 比较优化前后的响应时间
  2. 比较优化前后的吞吐量(QPS/TPS)
  3. 比较优化前后的资源使用率
  4. 比较优化前后的慢查询数量
  5. 进行压力测试,验证系统承载能力