管理

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

Posted on 2026-08-18 10:05  lzhdim  阅读(342)  评论(0)    收藏  举报
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;
  1. 分页优化,大 offset 不要直接 limit offset,size
--offset很大时性能差
select * from t limit 100000,10;
--优化:主键定位
select * from t where id>100000 limit 10;
  1. 避免大表 join,小表驱动大表
     
    inner join,把数据量小的表放前面;尽量减少 join 的表数量。
  2. in 与 exists 选择
  • 小集合用 in;子查询大结果集用 exists
  • 避免in()里面上万条数据。
  1. union 和 union all
     
    union会去重排序,开销大;不需要去重优先用union all
  2. where 条件过滤尽早执行
     
    把能过滤大量数据的条件写在 where,不要放到 having。
having 是分组后过滤;where 是分组前过滤。
--不好
select count(*) from t group by age having age>20;
--更好
select count(*) from t where age>20 group by age;
  1. 减少排序
    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 或者调整索引。
Copyright © 2000-2022 Lzhdim Technology Software All Rights Reserved