当前位置: 首页 > article >正文

Mysql在SQL层面的优化

以下是MySQL在SQL层面的优化方法及详细案例,结合实际场景说明如何通过调整SQL语句提升性能:


1. 确保索引有效使用

案例:订单状态查询优化

问题SQL

SELECT * FROM orders WHERE status = 'shipped' AND create_time > '2023-01-01';

分析

  • statuscreate_time字段无索引,会导致全表扫描。
  • 通过EXPLAIN查看执行计划,发现type=ALL(全表扫描)。

优化方法
添加联合索引:

ALTER TABLE orders ADD INDEX idx_status_create_time (status, create_time);

优化后效果

  • EXPLAIN显示type=range,索引生效,扫描行数大幅减少。

**2. 避免使用SELECT ***

案例:用户信息查询优化

问题SQL

SELECT * FROM users WHERE age > 30;

问题

  • SELECT *会读取所有字段,包括不需要的文本字段(如description),增加I/O和内存开销。

优化方法
明确指定所需字段:

SELECT user_id, name, age FROM users WHERE age > 30;

优化后效果

  • 减少数据传输量,尤其对大文本字段场景性能提升显著。

3. 分页查询优化

案例:日志表分页慢

问题SQL

SELECT * FROM logs ORDER BY id LIMIT 1000000, 10;

问题

  • LIMIT 1000000, 10会先扫描前1000010行,再丢弃前100万行,效率极低。

优化方法
改用游标分页(基于上一页最后一条记录的ID):

SELECT * FROM logs WHERE id > 1000000 ORDER BY id LIMIT 10;

优化后效果

  • 直接通过索引定位到起始点,扫描行数从100万+降低到10行。

4. 优化JOIN操作

案例:订单与用户表关联查询

问题SQL

SELECT * FROM orders 
LEFT JOIN users ON orders.user_id = users.id 
WHERE users.country = 'US';

问题

  • users.country无索引,会先全表扫描users,再关联orders表。

优化方法

  1. users.country添加索引:
    ALTER TABLE users ADD INDEX idx_country (country);
    
  2. 调整查询顺序,小表驱动大表:
    SELECT * FROM users 
    STRAIGHT_JOIN orders ON users.id = orders.user_id 
    WHERE users.country = 'US';
    

优化后效果

  • users表通过索引快速过滤,再关联orders表,减少扫描数据量。

5. 子查询优化

案例:查询未支付订单

问题SQL

SELECT * FROM orders 
WHERE user_id IN (SELECT user_id FROM payments WHERE status = 'failed');

问题

  • MySQL可能对子查询进行全表扫描,尤其数据量大时性能差。

优化方法
改写为JOINEXISTS

-- 使用JOIN
SELECT o.* FROM orders o 
INNER JOIN payments p ON o.user_id = p.user_id 
WHERE p.status = 'failed';-- 使用EXISTS
SELECT * FROM orders o 
WHERE EXISTS (SELECT 1 FROM payments p WHERE p.user_id = o.user_id AND p.status = 'failed'
);

优化后效果

  • 执行计划显示使用索引关联,避免全表扫描。

6. 避免索引失效操作

案例:日期范围查询

问题SQL

SELECT * FROM logs WHERE DATE(create_time) = '2023-10-01';

问题

  • 对字段使用函数DATE()会导致索引失效。

优化方法
改用范围查询:

SELECT * FROM logs 
WHERE create_time >= '2023-10-01 00:00:00' 
AND create_time < '2023-10-02 00:00:00';

优化后效果

  • create_time有索引,优化后查询可命中索引。

7. 利用覆盖索引

案例:统计用户数量

问题SQL

SELECT COUNT(*) FROM users WHERE age > 30;

问题

  • age字段无索引,需全表扫描。

优化方法

  1. 添加索引:
    ALTER TABLE users ADD INDEX idx_age (age);
    
  2. 使用覆盖索引(索引包含查询所需字段):
    SELECT COUNT(*) FROM users USE INDEX (idx_age) WHERE age > 30;
    

优化后效果

  • 直接从索引树统计数量,无需回表查数据行。

8. 减少全表排序(Using filesort)

案例:按姓名排序查询

问题SQL

SELECT * FROM employees ORDER BY name LIMIT 1000;

问题

  • 若无name索引,需全表扫描后排序,产生Using filesort

优化方法
添加索引:

ALTER TABLE employees ADD INDEX idx_name (name);

优化后效果

  • EXPLAIN显示Using index,直接按索引顺序返回数据。

9. 批量插入优化

案例:导入大量数据

问题SQL

INSERT INTO logs (message) VALUES ('msg1');
INSERT INTO logs (message) VALUES ('msg2');
... (重复1万次)

问题

  • 每次插入都提交事务,导致频繁I/O。

优化方法
使用批量插入:

INSERT INTO logs (message) VALUES 
('msg1'), ('msg2'), ..., ('msg10000');

优化后效果

  • 单次事务提交,减少磁盘I/O和锁竞争。

10. 类型匹配避免隐式转换

案例:按字符串ID查询

问题SQL

SELECT * FROM products WHERE id = '100'; -- id为INT类型

问题

  • 字符串'100'INT类型不匹配,导致索引失效。

优化方法
保持类型一致:

SELECT * FROM products WHERE id = 100;

优化后效果

  • 索引命中,避免全表扫描。

总结

SQL层面优化的核心原则:

  1. 索引为王:确保查询条件、JOIN字段、排序字段有合适索引。
  2. 减少数据量:避免不必要的数据传输(如SELECT *)。
  3. 避免索引失效:注意函数、类型转换、运算对索引的影响。
  4. 重写复杂查询:用JOIN替代子查询,用游标分页替代LIMIT OFFSET

工具辅助

  • 使用EXPLAIN分析执行计划,关注typekeyrowsExtra列。
  • 开启慢查询日志(slow_query_log)定位高频低效SQL。
http://www.lryc.cn/news/2386605.html

相关文章:

  • JVM规范之栈帧
  • 【C++指南】string(四):编码
  • 深度学习之序列建模的核心技术:LSTM架构深度解析与优化策略
  • AI量化交易是什么?它是如何重塑金融世界的?
  • 分布式事务处理方案
  • CVE-2024-36467 Zabbix权限提升
  • Dify中的自定义模型插件开发例子:以xinference为例
  • crud方法命名示例
  • 尚硅谷redis7 33-36 redis持久化之RDB优缺点及数据丢失案例
  • No such file or directory: ‘ffprobe‘
  • 计算机网络-WebSocket/DNS/Cookie/Session/Token/Jwt/Nginx
  • 功能“递归模式”在 C# 7.3 中不可用,请使用 8.0 或更高的语言版本的一种兼容处理方案
  • 第4章-操作系统知识
  • 将网页带格式转化为PDF
  • 【ArcGIS】ArcGIS AI 助手----复现
  • 使用 FFmpeg 将视频转换为高质量 GIF(保留原始尺寸和帧率)
  • 《Java vs Go vs C++ vs C:四门编程语言的深度对比》
  • 充电枪IEC62196/EN 62196测试内容
  • 有效的字母异位符--LeetCode
  • SAP ERP 系统拆分的七大挑战
  • AcrelEMS 3.0智慧能源管理平台:构建企业微电网数智化中枢
  • 【HTML-12】HTML表格常用属性详解:从基础到高级应用
  • Word转PDF--自动生成目录
  • MySQL组合索引优化策略
  • Spring MVC 的的核心原理与实践指南
  • 轻量级视觉语言模型 Dolphin:高效精准的文档结构化解析利器
  • 如何安全配置数据库(MySQL/PostgreSQL/MongoDB)
  • 将 Docker 镜像从服务器A迁移到服务器B的方法
  • git merge解冲突后,add、continue提交
  • Lines of Thought in Large Language Models