提高 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 或者调整索引。

相关推荐
2302_1116 分钟前
java依赖小结
java·运维·数据库
sunshine22 girl8 分钟前
Java学习三 高级语法3, 方法
java·学习
YMWM_20 分钟前
查看realsense相机序列号脚本
开发语言·python·数码相机
听到微笑32 分钟前
Elasticsearch 如何存储与检索海量向量
数据库·elasticsearch
captain37638 分钟前
网络原理(3)-TCP核心机制连接管理▲▲▲
java·服务器·网络·ide·网络协议·tcp/ip·java-ee
传奇开心果编程41 分钟前
【dioxus0.7基础语法学与练】第8课:RSX 宏 — Dioxus 声明式 UI 语法
开发语言·学习·rust
海浪仙人掌1 小时前
速动比率怎么分析?速动比率分析有哪些注意事项?
大数据·数据库·人工智能
企业数字化笔记1 小时前
固定资产历史数据怎么导入系统?Excel模板、字段映射和数据校验
android·java·数据库·后端
troy1281 小时前
Python 基础语法(一):变量、数据类型与运算符
java·服务器·python
wuyk5551 小时前
18.Kruskal 算法:用最短的边连成一张网
开发语言·算法·图论