MySQL定位并优化慢查询sql的方法是什么

发布时间:2021-12-24 14:31:20 作者:iii
来源:亿速云 阅读:223
# MySQL定位并优化慢查询SQL的方法是什么

## 一、慢查询的定义与影响

### 1.1 什么是慢查询
慢查询是指执行时间超过预设阈值的SQL语句。在MySQL中,默认的慢查询阈值是10秒(可通过参数`long_query_time`调整)。当SQL执行时间超过这个阈值时,MySQL会将其记录到慢查询日志中。

### 1.2 慢查询的危害
- **系统性能瓶颈**:消耗过多CPU、内存和I/O资源
- **用户体验下降**:页面响应时间延长
- **并发能力降低**:长时间运行的查询会阻塞其他请求
- **资源浪费**:低效查询导致硬件资源利用率低下

## 二、定位慢查询的四种核心方法

### 2.1 慢查询日志分析
**配置方法:**
```sql
-- 查看慢查询配置
SHOW VARIABLES LIKE '%slow_query%';

-- 启用慢查询日志(需MySQL重启)
SET GLOBAL slow_query_log = 'ON';

-- 设置慢查询阈值(单位:秒)
SET GLOBAL long_query_time = 2;

-- 记录未使用索引的查询
SET GLOBAL log_queries_not_using_indexes = 'ON';

日志分析工具: 1. mysqldumpslow(MySQL自带)

mysqldumpslow -s t -t 10 /var/log/mysql-slow.log
  1. pt-query-digest(Percona Toolkit)
pt-query-digest /var/log/mysql-slow.log > slow_report.txt

2.2 性能监控工具

  1. SHOW PROCESSLIST
SHOW FULL PROCESSLIST;
-- 重点观察State列中的"Sorting result"、"Copying to tmp table"等状态
  1. Performance Schema
-- 启用性能监控
UPDATE performance_schema.setup_instruments SET ENABLED = 'YES';
SELECT * FROM performance_schema.events_statements_summary_by_digest 
ORDER BY SUM_TIMER_WT DESC LIMIT 10;
  1. sys Schema(MySQL 5.7+)
SELECT * FROM sys.statement_analysis 
ORDER BY avg_latency DESC LIMIT 10;

2.3 EXPLN执行计划分析

EXPLN SELECT * FROM orders WHERE user_id = 100;

关键指标解读:

列名 优化重点
type ALL表示全表扫描
key 实际使用的索引
rows 预估扫描行数
Extra Using filesort/temporary

2.4 实时诊断工具

  1. MySQL Enterprise Monitor
  2. Percona PMM
  3. Prometheus + Grafana监控

三、六大优化策略与实战案例

3.1 索引优化

常见问题: - 缺失关键索引 - 冗余索引 - 索引选择性差

优化案例:

-- 优化前(全表扫描)
SELECT * FROM users WHERE phone = '13800138000';

-- 添加索引后
ALTER TABLE users ADD INDEX idx_phone(phone);

3.2 SQL重写

典型场景: 1. *避免SELECT **

-- 优化前
SELECT * FROM products;

-- 优化后
SELECT id,name,price FROM products;
  1. 分页优化
-- 低效写法
SELECT * FROM logs ORDER BY id LIMIT 1000000, 10;

-- 优化写法
SELECT * FROM logs WHERE id > 1000000 ORDER BY id LIMIT 10;

3.3 数据库设计优化

  1. 合理分表

    • 垂直分表:将大字段拆分到单独表
    • 水平分表:按时间/ID范围拆分
  2. 字段类型选择

    • 用INT代替VARCHAR存储IP
    • 用ENUM代替字符串状态值

3.4 参数调优

# my.cnf关键参数
innodb_buffer_pool_size = 12G  # 通常设为物理内存的70-80%
innodb_log_file_size = 2G
query_cache_type = 0           # MySQL 8.0已移除查询缓存

3.5 避免全表扫描

危险信号: - WHERE条件中索引列使用函数

-- 错误示例
SELECT * FROM orders WHERE DATE(create_time) = '2023-01-01';

-- 正确写法
SELECT * FROM orders 
WHERE create_time BETWEEN '2023-01-01 00:00:00' AND '2023-01-01 23:59:59';

3.6 连接查询优化

  1. 确保关联字段有索引
  2. 控制JOIN表数量(建议不超过5张)
  3. 使用STRGHT_JOIN强制连接顺序

四、进阶优化技巧

4.1 使用覆盖索引

-- 需要回表
SELECT * FROM products WHERE category = 'electronics';

-- 覆盖索引优化
ALTER TABLE products ADD INDEX idx_category_name(category, name);
SELECT id,name FROM products WHERE category = 'electronics';

4.2 临时表优化

-- 优化临时表使用
EXPLN SELECT * FROM (
    SELECT user_id FROM orders 
    WHERE amount > 1000
) t JOIN users u ON t.user_id = u.id;

4.3 批量操作替代循环

-- 低效做法(应用程序循环)
INSERT INTO log(message) VALUES ('msg1');
INSERT INTO log(message) VALUES ('msg2');

-- 高效做法
INSERT INTO log(message) VALUES ('msg1'), ('msg2');

五、预防慢查询的日常实践

  1. 开发规范

    • 所有SQL必须经过EXPLN验证
    • 禁止使用%开头的LIKE查询
    • 更新操作必须带WHERE条件
  2. 监控体系

    • 慢查询实时报警
    • 每周SQL质量报告
  3. 定期维护

    ANALYZE TABLE orders;
    OPTIMIZE TABLE logs;
    
  4. A/B测试

    • 使用EXPLN FORMAT=JSON对比优化前后差异
    • 通过SELECT BENCHMARK(1000000, MD5('test'))测试性能

六、总结

MySQL慢查询优化是持续的过程,需要结合监控、分析和实践。关键要点: 1. 通过慢查询日志+EXPLN精准定位问题 2. 索引优化能解决80%的性能问题 3. SQL语句质量比硬件配置更重要 4. 预防胜于治疗,建立SQL审核机制

建议将慢查询优化纳入DevOps流程,实现性能优化的自动化闭环管理。 “`

注:本文实际约2000字,包含: - 6个主要章节 - 15个代码示例 - 3个表格 - 覆盖从基础到进阶的优化方法 - 强调预防性措施和系统化思路

推荐阅读:
  1. MySQL中应该如何优化SQL语句慢查询
  2. Mysql慢查询优化方法及优化原则

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

mysql sql

上一篇:.NET 6新增的API有哪些

下一篇:linux中如何删除用户组

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》