目录
[1. 高频查询字段合理建索引](#1. 高频查询字段合理建索引)
[2. 优先使用联合索引,遵循最左匹配原则](#2. 优先使用联合索引,遵循最左匹配原则)
[3. 大量业务场景使用覆盖索引,彻底杜绝回表](#3. 大量业务场景使用覆盖索引,彻底杜绝回表)
[4. 永远优先使用主键查询](#4. 永远优先使用主键查询)
[1. 禁止使用 SELECT *](#1. 禁止使用 SELECT *)
[2. 杜绝索引失效写法](#2. 杜绝索引失效写法)
[3. 优化大表分页查询](#3. 优化大表分页查询)
[1. 避免大SQL、大事务](#1. 避免大SQL、大事务)
[2. 分页、限流兜底](#2. 分页、限流兜底)
[3. 合理使用读写分离](#3. 合理使用读写分离)
[1. 开启慢查询日志,定期优化Top慢SQL](#1. 开启慢查询日志,定期优化Top慢SQL)
[2. 避免临时表、文件排序](#2. 避免临时表、文件排序)
基于索引树、叶子节点、回表、覆盖索引、联合索引底层原理,整理线上最常用、最落地的SQL优化方案,所有方法均贴合真实业务场景,无空泛理论。
一、索引层面优化(核心提速手段,效果最明显)
1. 高频查询字段合理建索引
针对 WHERE、JOIN、ORDER BY、GROUP BY 高频字段建立索引,避免全表扫描。禁止给性别、订单状态、是否删除等低区分度字段单独建索引,极易出现索引失效、开销大于全表扫描的问题。
2. 优先使用联合索引,遵循最左匹配原则
多条件查询场景,优先建立联合索引而非多个单字段索引。将高区分度、高频筛选字段放在索引前置位,排序分组字段后置,严格遵循最左匹配规则,避免索引失效。
3. 大量业务场景使用覆盖索引,彻底杜绝回表
这是业务最优解之一。查询所需的所有字段全部放入联合索引,让二级索引叶子节点包含全部查询数据,无需回表查询聚簇索引,性能无限接近主键查询。只要查询字段不超出索引范围,就能实现零回表极速查询。
4. 永远优先使用主键查询
主键自带聚簇索引,叶子节点存储整行数据,无回表开销,是MySQL查询性能天花板。大表分页、精准查询优先用主键定位,替代普通条件查询。
**业务中哪些场景必须建索引?哪些场景不建议建?**下面结合电商业务说明:
必须建索引的业务场景:
1)WHERE 高频筛选字段:电商订单表的 user_id、order_status、create_time,用户查询我的订单、筛选待付款订单是高频操作,无索引会全表扫描,接口超时。
2)JOIN 关联字段:订单表 order_id 关联订单详情表、用户表 user_id 关联收货地址表,关联字段必须建索引,避免联表查询巨慢。
3)ORDER BY/GROUP BY 排序分组字段:商品列表按 price 价格排序、订单按 create_time 倒序,索引可避免文件排序、临时表。
4)唯一约束字段:用户手机号、账号、订单编号,使用唯一索引,保证业务唯一性,同时提升查询效率。
不建议建索引的场景:
1)数据量极小的表(100行以内):全表扫描开销低于索引查询。
2)更新、删除极频繁,查询极少的字段:比如订单临时备注字段,频繁修改会导致索引频繁失效、重建,增加IO开销。
3)区分度极低的字段:比如订单状态只有0/1/2三种值,性别男/女,索引失效,无法过滤数据。
4)大文本字段:text、longtext,不适合建普通索引,如需检索使用全文索引。
二、SQL语句写法优化(零成本提速,规避隐形失效)
1. 禁止使用 SELECT *
SELECT * 会查询全表所有字段,无法触发覆盖索引、强制触发回表、增加网络IO和内存开销。业务中按需查询指定字段,既能适配覆盖索引,又能减少数据传输量。
2. 杜绝索引失效写法
以下写法会直接导致索引失效、走全表扫描,日常开发严格规避:
-
模糊查询左匹配、全匹配:
LIKE '%xxx' / LIKE '%xxx%' -
字段隐式类型转换(字符串字段传数字、数字字段传字符串)
-
索引字段使用函数、运算:
DATE(create_time)、user_id+1 -
OR 连接无索引字段、IN 超大集合(建议控制在1000以内)
3. 优化大表分页查询
传统 LIMIT 10000,10 深分页会扫描并丢弃大量无效数据,IO开销极高。优化方案:主键回溯分页 ,通过 WHERE id > 10000 LIMIT 10 直接定位数据位置,无需扫描前置无效数据。
三、业务逻辑与数据层优化(高并发场景必备)
1. 避免大SQL、大事务
单条SQL禁止关联多张大表、禁止一次性查询海量数据;大事务拆分短事务,减少锁持有时间、减少MVCC版本链堆积,避免查询卡顿、锁等待超时问题。下面结合电商订单下单业务,举实战例子清晰区分优劣:
❌ 错误写法:超大长事务(线上高危)
开启一个事务,一次性执行4步操作,全程不提交,锁长期占用:
- 查询商品库存、锁定库存(加行锁) 2. 创建主订单数据(加行锁) 3. 批量写入10+条订单详情数据 4. 更新用户积分、更新商家销售额 最后统一提交事务
引发问题 :整个流程耗时几百毫秒甚至1秒,库存、订单行锁长时间不释放,大量并发下单会触发锁等待超时、死锁;同时事务期间数据多次修改,MVCC版本链疯狂堆积,导致普通查询变慢、数据库CPU升高。
✅ 优化写法:拆分为多个短事务(线上标准规范)
拆解独立操作,分步执行、即时提交,缩短锁持有时间:
事务1:查询并锁定库存、校验库存,提交事务(快速释放库存锁) 事务2:创建主订单、写入订单详情,提交事务(快速释放订单锁) 事务3:异步更新用户积分、商家数据(可通过MQ异步解耦,无需事务强一致)
优化效果:单个事务执行时间压缩至几十毫秒,行锁快速释放、不堆积;MVCC版本链干净,查询无卡顿,并发能力大幅提升,彻底解决大事务引发的慢查询、超时问题。
2. 分页、限流兜底
业务层限制最大查询条数,禁止一次性查询全表数据;列表查询强制分页,杜绝无分页的全表遍历SQL,保护数据库并发能力。
3. 合理使用读写分离
读多写少业务,写操作走主库,高并发查询、非实时统计查询走从库,分担主库压力,避免读流量压垮主库,提升整体查询响应速度。
四、数据库配置与兜底优化(线上稳定性优化)
1. 开启慢查询日志,定期优化Top慢SQL
通过慢查询日志定位超时SQL,使用 EXPLAIN 分析执行计划,重点优化 type=ALL、存在Using filesort、Using temporary的低效SQL。
2. 避免临时表、文件排序
合理设计索引,让 ORDER BY、GROUP BY 走索引排序,避免数据库临时排序和临时表创建,大幅降低CPU开销。
五、终极优化优先级
主键查询 > 覆盖索引查询 > 普通索引精准查询 > 优化SQL写法规避索引失效 > 分页/事务优化 > 读写分离架构优化