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

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.xdnf.cn/news/657775.html

相关文章:

  • [Java实战]SpringBoot集成SNMP实现OID数据获取:原理、实践与测试(三十三)
  • GitLab 从 17.10 到 18.0.1 的升级指南
  • 动态规划-918.环形子数组的最大和-力扣(LeetCode)
  • SQL Driver
  • 16QAM通信系统设计与实现(上篇)——信号生成与调制技术(python版本)
  • leetcode 525. 连续数组
  • CertiK联创顾荣辉做客纽交所,剖析Bybit与Coinbase事件暴露的Web3安全新挑战
  • 原子操作(C++)
  • 深度体验:海螺 AI,开启智能创作新时代
  • liunx、ubantu22.04安装neo4j数据库并设置开机自启
  • AI工程师跑路了-SpringAi来帮忙
  • 学习路之PHP--easyswoole安装入门
  • LINUX安装运行jeelowcode前端项目
  • SC89171的介绍和使用
  • 炫云云渲染,构筑虚实交融的3D数字新视界
  • AI的“软肋”:架构设计与业务分析的壁垒
  • OpenCV CUDA模块图像过滤------创建一个行方向的一维积分(Sum)滤波器函数createRowSumFilter()
  • 爬虫IP代理效率优化:策略解析与实战案例
  • Neo4j(三) - 使用Java操作Neo4j详解
  • 第12次05: 用户中心-用户基本信息
  • 如何用ChatGPT提升学术长文质量
  • Golang Gin框架基础与实践指南
  • 【学习笔记】GitLab 下载安装与配置
  • 算力服务器的应用场景都有哪些
  • 学习python day8
  • 超临界机组协调控制系统建模项目开发笔记
  • git 删除某个远程库的分支
  • 【Redis】第1节|Redis服务搭建
  • 【freertos-kernel】queue(创建)
  • 企业网络综合实训