提高 SQL 语句执行速度的方法

SQL 优化核心思路:减少扫描的数据量、减少回表、避免全表扫描、合理利用索引、优化 SQL 写法、调整数据库配置。

一、索引优化(最常用)

  1. 建立合适索引
  • where、join、order by、group by 后的字段适合建索引。

  • 联合索引遵循最左前缀原则,把查询高频、筛选度高的字段放左边。

    --联合索引:col1,col2,col3,where条件要尽量带上col1
    create index idx_col1_col2_col3 on table(col1,col2,col3);

  1. 避免索引失效(重点)
  • 不要对索引列做运算、函数、隐式类型转换

    --失效,索引列做函数
    select * from t where date(create_time)='2026‑08‑18';
    --改写
    select * from t where create_time >= '2026‑08‑18' and create_time < '2026‑08‑19';

  • like '%xxx' 前缀通配符会失效;like 'xxx%'可以走索引

  • or 一边无索引容易失效,可以改用union all替代 or

  • 避免 is not null!=<> 会导致放弃索引(数据分布不同情况不一样)

  1. 不要滥用索引
    索引会加快查询,但减慢 insert/update/delete,每修改数据要维护索引。一张表索引不宜过多。

  2. 覆盖索引
    查询的列全部在索引里,不需要回表读取原表,性能很高。

    --索引包含id,name,直接从索引拿数据,不用回表
    select id,name from t where id>100;

二、SQL 语句写法优化

  1. ** 不要 select ***,只查询需要的字段,减少数据传输,利于覆盖索引

    --不好
    select * from user;
    --好
    select id,name,phone from user;

  2. 分页优化,大 offset 不要直接 limit offset,size

    --offset很大时性能差
    select * from t limit 100000,10;
    --优化:主键定位
    select * from t where id>100000 limit 10;

  3. 避免大表 join,小表驱动大表

  4. in 与 exists 选择

  • 小集合用 in;子查询大结果集用 exists
  • 避免in()里面上万条数据。
  1. union 和 union all union会去重排序,开销大;不需要去重优先用union all

  2. where 条件过滤尽早执行
    having 是分组后过滤;where 是分组前过滤。

    --不好
    select count() from t group by age having age>20;
    --更好
    select count(
    ) from t where age>20 group by age;

  3. 减少排序order bygroup bydistinct会产生文件排序,尽量利用索引有序特性避免 filesort。

三、表结构设计优化

  1. 字段尽量小,选用合适数据类型,避免大字段(text/blob)频繁查询;大字段拆分到单独表。
  2. 尽量用主键 int/bigint,避免字符串做主键。
  3. 适当分表分库:数据量千万级别以上,考虑水平分表、垂直分表。
  4. 合理设置主键,InnoDB 主键建议自增,减少页分裂。

四、数据库层面优化

  1. explain 分析执行计划

    explain select xxx from table where xxx;

重点看:

  • type:优先ref/range,尽量避免ALL全表扫描
  • key:实际使用的索引,null 代表没用到索引
  • rows:预估扫描行数,越小越好
  • Extra:看到Using filesort(文件排序)、Using temporary(临时表)说明需要优化
  1. InnoDB 配置调优
  • innodb_buffer_pool_size:缓存数据与索引,机器内存 50‑70%,减少磁盘 IO。
  • 避免锁等待:大事务拆成小事务,减少行锁持有时间。

五、业务层面优化

  1. 缓存:热点数据放入 Redis,减少数据库查询。
  2. 读写分离:读多写少场景,主库写,从库承担查询。
  3. 避免一次性查询大量数据,分批查询,防止一次性把数据库打满。
  4. 统计报表不要直接跑在线业务库,同步数据到数库做统计。

六、常见坑总结

  1. 索引建了但是不走:函数、隐式转换、like 前缀 %、or 条件、统计信息不准。
  2. limit 大偏移分页慢。
  3. select * 浪费 IO,无法触发覆盖索引。
  4. 大事务、多表 join、临时表、文件排序。

简单排查步骤:先用explain看执行计划,确认是否全表扫描、索引是否生效,再改写 SQL 或者调整索引。

相关推荐
JavaPub-rodert1 小时前
王仕宇在 Go Context 如何解决协程泄漏与超时控制
开发语言·后端·golang·iphone·javapub·王仕宇
ltl1 小时前
ClickHouse Distributed 引擎与分布式查询路由
数据库
Wang's Blog1 小时前
PostgreSQL笔记60: 权限与角色管理——从层级体系到最佳实践
数据库·笔记·postgresql
深漂的华哥2 小时前
Ruoyi-Plus前后端分离场景下,数据加密传输
java·spring boot·后端·开源·maven·ruoyi
whcyhhh2 小时前
头歌实践教学平台:大数据存储2023(六)
大数据·数据库·python
ly76893 小时前
JavaScript 从入门到进阶:核心语法、异步编程与工程化实践
开发语言·javascript·ecmascript
落魄大学生之流水线上谋生计3 小时前
Java锁全面指南:从基础概念到企业级应用
java·开发语言
for_ever_love__3 小时前
python基础语法学习: 闭包
开发语言·python·学习·闭包
ly76893 小时前
Python 全面入门:从核心语法到工程实践
开发语言·python