惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google DeepMind News
Google DeepMind News
F
Fortinet All Blogs
量子位
G
Google Developers Blog
J
Java Code Geeks
N
Netflix TechBlog - Medium
博客园 - 聂微东
宝玉的分享
宝玉的分享
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
月光博客
月光博客
The Cloudflare Blog
Apple Machine Learning Research
Apple Machine Learning Research
爱范儿
爱范儿
雷峰网
雷峰网
M
MIT News - Artificial intelligence
T
Tailwind CSS Blog
V
Visual Studio Blog
阮一峰的网络日志
阮一峰的网络日志
博客园 - 三生石上(FineUI控件)
Microsoft Azure Blog
Microsoft Azure Blog
aimingoo的专栏
aimingoo的专栏
Martin Fowler
Martin Fowler
有赞技术团队
有赞技术团队
T
The Blog of Author Tim Ferriss

博客园 - lzhdim

25个每个开发人员都应该掌握的JavaScript 数组方法 20260831 - 个人小作品更新 C#使用SQLite数据库例子 - 开源研究系列文章 20260830 - 个人小作品更新 20260829 - 个人小作品更新 13、JavaScript事件循环机制 - JavaScript学习系列文章 首款媲美分体水冷的一体水冷!微星CORELIQUID E15 360水冷散热器评测:目前为止 锐龙9 9950X3D最强性能释放 JavaScript常见的内存泄露问题 - JavaScript学习系列文章 C#开发的颜色取色器 - 开源研究系列文章 - 个人小作品 成长环境 - 我的闪存 JavaScript安全最佳实践 关闭iPhone一些默认设置,让iPhone更流畅 20260814 - 个人小作品更新 JavaScript对象与元编程 20260812 - 个人小作品更新 JavaScript 模块化系统 Markdown 语法完全指南 C# 通过 Windows API 实现进程内存读写操作 JavaScript 函数进阶课题 C#开发的基于钩子技术监测键鼠事件的例子 - 开源项目研究文章 JavaScript异步编程的演进 近十年最帅风冷!酷冷至尊V8 ACE 3DHP散热器评测:单塔能干翻双塔 20260723 - 个人小作品更新 C# 中读取CPU、硬盘和内存温度 雷柏VT3s MAX鼠标评测:中小手型用户也没有被遗忘 顶尖性能的小号电竞鼠标来了 JavaScript 中的原型与继承 1分钟查清局域网所有IP 20260714 - 个人小作品更新 WorkBuddy 完整教程手册 专为AI而生的企业级QLC SSD!长江存储PE501 61.44TB评测:超过1PB的写入测试
提高 SQL 语句执行速度的方法
lzhdim · 2026-08-18 · via 博客园 - lzhdim

Posted on 2026-08-18 10:05  lzhdim  阅读(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 或者调整索引。