SQL优化十大技巧,查询速度提升10倍!
摘要: 本文分享了10个实用的SQL优化技巧,帮助提升查询性能。包括避免使用SELECT *、合理使用LIMIT、通过EXPLAIN分析查询计划、为高频字段添加索引、避免在WHERE子句中使用函数、用JOIN替代子查询、用IN或UNION代替OR条件、批量操作减少交互、使用EXISTS替代IN以及定期优化表碎片整理。此外还建议先优化SQL再考虑硬件配置,通过EXPLAIN定位问题。这些技巧简单易用
📌 今日关键词:查询加速、性能提升、避坑指南
大家好呀!我是数据库小学妹👋
上午我们学了权限管理,给数据库上了“安全锁”🔒,下午咱们来给查询“踩油门”🚀!
你是不是遇到过这种情况:一条SQL语句跑半天不出结果,数据库像卡住的拖拉机?🤯 别急!今天分享10个超实用的SQL优化技巧,让查询速度飞起来,甚至提升10倍!💥 这些技巧都是小学妹踩过无数坑总结出来的,保证简单易懂,新手也能立刻用上!✌️
🔥 SQL优化十大技巧(附避坑指南)
1️⃣避免用 SELECT *,只查需要的字段
原因: SELECT * 会返回所有列,浪费带宽和内存,尤其大表更明显。
优化: 明确指定需要的字段,比如 SELECT id, name。
-- ❌ 错误
SELECT * FROM users WHERE age > 18;
-- ✅ 正确
SELECT id, name, age FROM users WHERE age > 18;
避坑: 别偷懒写 SELECT *,特别是生产环境的大表!
2️⃣ 用 LIMIT 限制结果数量
原因: 返回过多数据会导致内存溢出或网络延迟。
优化: 例如只查前100条。
-- ❌ 错误(logs表可能有几百万行)
SELECT * FROM logs ORDER BY id DESC;
-- ✅ 正确
SELECT * FROM logs ORDER BY id DESC LIMIT 100;
避坑: 分页查询时,避免用 LIMIT 100 OFFSET 100000(偏移量大时性能差),可以用“游标分页”或记录上次ID。
3️⃣ 合理使用 EXPLAIN 分析查询计划
原因: 查看SQL是否用了索引,避免低效执行。
优化: 执行 EXPLAIN SELECT ...;,关注 type(ALL是全表扫描,需优化!)。
EXPLAIN SELECT id, name FROM users WHERE age > 18;
避坑: 别盲目优化,先 EXPLAIN 找准问题再动手!
4️⃣给高频查询字段加索引
原因: 索引像书的目录,大幅加快查询速度。
优化: 为 WHERE、JOIN、ORDER BY 的列建索引。
-- 经常按 age 查询,就给 age 加索引
CREATE INDEX idx_age ON users(age);
避坑: 索引不是越多越好!过多索引会增加写操作(INSERT/UPDATE/DELETE)的成本。
5️⃣ 避免在 WHERE 子句中对索引列使用函数或表达式
原因: 例如 WHERE DATE(created_at) = '2026-01-01' 会让索引失效,导致全表扫描。
优化: 改成范围查询。
-- ❌ 错误
SELECT * FROM orders WHERE DATE(create_time) = '2026-01-01';
-- ✅ 正确
SELECT * FROM orders WHERE create_time >= '2026-01-01' AND create_time < '2026-01-02';
避坑: 同样的,WHERE UPPER(name) = 'TOM' 也会让索引失效,建议存数据时就统一大小写。
6️⃣用 JOIN 代替子查询**(复杂场景)**
原因: 子查询可能被重复执行,效率低。
优化: 用 INNER JOIN 合并关联表查询。
-- ❌ 较慢(子查询)
SELECT * FROM users WHERE id IN (SELECT user_id FROM orders);
-- ✅ 较快(JOIN)
SELECT DISTINCT users.* FROM users INNER JOIN orders ON users.id = orders.user_id;
避坑: 但 JOIN 的表太多(超过3-4张)也会变慢,需平衡。
7️⃣避免 OR 条件,用 IN 或 UNION 替代
原因: WHERE id = 1 OR id = 2 可能让索引失效。
优化: 改用 IN 或 UNION。
-- ❌ 可能慢
SELECT * FROM users WHERE id = 1 OR id = 2;
-- ✅ 更好
SELECT * FROM users WHERE id IN (1, 2);
-- ✅ 或者用 UNION(适用于不同字段)
SELECT * FROM users WHERE name = 'Tom' UNION SELECT * FROM users WHERE name = 'Jerry';
避坑: IN 列表数据量太大(超过几百个)时也会慢,需测试。
8️⃣批量操作优于单条操作
原因: 减少与数据库的交互次数,降低网络开销。
优化: 例如用一条 INSERT 插入多行。
-- ❌ 单条插入(慢)
INSERT INTO users (name) VALUES ('Tom');
INSERT INTO users (name) VALUES ('Jerry');
-- ✅ 批量插入(快)
INSERT INTO users (name) VALUES ('Tom'), ('Jerry');
避坑: 批量数据别太大,建议每批500-1000行,否则可能内存溢出或事务过大。
9️⃣用 EXISTS 代替 IN(子查询返回大量数据时)
原因:IN 会把子查询结果全部加载到内存,而 EXISTS 一找到匹配就返回。
优化:改写为 EXISTS。
-- ❌ 子查询返回大量数据时慢
SELECT * FROM users WHERE id IN (SELECT user_id FROM orders);
-- ✅ 更快
SELECT * FROM users WHERE EXISTS (SELECT 1 FROM orders WHERE orders.user_id = users.id);
避坑: 如果子查询结果集很小(比如几十条),IN 和 EXISTS 差别不大。
🔟定期优化表(碎片整理)
原因:频繁增删改后,表会产生碎片,影响查询性能。
优化:执行 OPTIMIZE TABLE(InnoDB 也支持)。
OPTIMIZE TABLE users;
避坑:高并发时避免执行,会锁表!建议在业务低峰期(如凌晨)执行。
💡 额外彩蛋:硬件与配置优化(终极杀招)
好马配好鞍,硬件和配置是基础。但先优化SQL,再考虑硬件,别本末倒置!
- 升级内存/SSD
- 调整
innodb_buffer_pool_size(MySQL缓存,建议设为物理内存的70%-80%) - 开启慢查询日志,针对性优化
优化不是一蹴而就的,先用 EXPLAIN 看执行计划,找到慢的原因再下手。很多时候,加一个索引、改一个 SELECT *,速度就能翻倍。
这些技巧我每天写SQL时都会下意识用上,慢慢就成习惯了。你也试试看~
👋 我是数据库小学妹一个用设计师思维学数据库的转行人。我们一起,把复杂的技术变得简单有趣!💕
本文技巧适用于MySQL 8.0,不同数据库版本可能有差异,建议先测试再上线。
更多推荐


所有评论(0)