mysql教程实战指南:查询语句优化与索引设计核心技巧

admin 数据库教程 3


嘿,用 MySQL 的朋友们,兔子哥今天来聊聊实战中最头疼的问题。是不是写的查询语句跑起来慢吞吞,几万条数据查半天?建了索引却没效果,EXPLAIN 分析一脸懵?别愁,今天这篇实战指南就聚焦查询语句优化和索引设计,全是干活儿的技巧,新手也能跟着学,一起往下看吧!
先说说为啥这俩技能重要。有粉丝 @老周 私信说:“做报表时一个查询卡了 5 分钟,领导催得急,自己满头汗,最后发现就是语句没写对。” 其实呀,查询慢、索引失效,多半不是数据太多,而是方法没找对。先给大家看张对比表,感受下优化前后的差距:
场景未优化情况优化后效果核心优化点
单表查询全表扫描,10 万条数据查 3 秒走索引,查 0.1 秒加合适索引,避免 select *
多表联查嵌套子查询,查 5 秒改 join 关联,查 0.5 秒优化 join 顺序,加关联字段索引
条件筛选用 or 连接多个条件,查 2 秒拆成 union 或加复合索引,查 0.3 秒避免 or,用索引覆盖

一、查询语句优化:从 “能跑” 到 “快跑” 的 5 个实战技巧


1. 别再用 select * 了,按需查字段


很多新手图省事,上来就写select * from table,这是大忌讳!*会查所有字段,包括不需要的,不仅传输数据多,还可能用不上索引。比如只需要查姓名和年龄,就写成select name, age from student,这样如果有 (name, age) 的索引,直接走索引覆盖,速度快一倍。
之前帮同事看一个慢查询,就是因为用了 select *,表有 20 多个字段,实际只需要 3 个,改成指定字段后,查询时间从 2 秒降到 0.2 秒,立竿见影。

2. where 子句别瞎写,这些坑要避开


where 条件是优化的关键,这几个错误新手常犯:
  • 别在字段上做运算,比如where age + 1 = 20,这样索引会失效,改成where age = 19
  • 别用like '%开头',比如where name like '%三',索引用不上,改成where name like '张%'(前缀匹配);
  • 少用 or,用 or 连接多个条件会让索引失效,比如where age = 18 or age = 20,可以改成where age in (18,20),或者加索引后用 union。

3. 多表联查:join 比子查询更高效


新手爱用嵌套子查询,比如select * from a where id in (select id from b),数据量大的时候特别慢。改成 join 关联会好很多:select a.* from a join b on a.id = b.id
记住 join 顺序也很重要,小表驱动大表(用小表的数据去匹配大表),比如 a 表 100 条,b 表 10 万条,就用 a join b,而不是 b join a,这样循环次数更少。

4. 分页查询别用 limit offset,越往后越慢


查第 100 页数据,写成limit 10000, 10,MySQL 会先查 10010 条再丢前 10000 条,很慢。优化方法:用主键排序后分页,比如select * from table where id > 10000 limit 10,前提是 id 有序且有索引,这样直接定位到 10000 后的位置,速度快多了。

5. 用 explain 分析语句,哪里慢一看就知


不会优化就用 explain!在查询前加 explain,比如explain select * from student where age = 18,看结果里的 type 字段:
  • type 是 ALL,说明全表扫描,要加索引;
  • type 是 ref 或 range,说明用上索引了,基本没问题;
  • key 字段显示 NULL,说明没走索引,得检查 where 条件或索引设计。

二、索引设计:不是越多越好,这些核心原则要记牢


1. 单字段索引:选查询频繁的字段


索引不是建得越多越好,每个索引会占空间,还会拖慢插入更新速度。单字段索引优先给这些字段建:
  • where 子句里频繁出现的字段,比如where age = ...就给 age 建索引;
  • 排序字段,比如order by create_time就给 create_time 建索引;
  • 分组字段,比如group by category就给 category 建索引。

但要注意,低频查询的字段别建索引,比如一年查不了几次的状态字段,建了也是浪费。

2. 复合索引:按 “最左前缀” 原则设计


多个条件查询时,单字段索引不够用,得建复合索引,比如where age = 18 and name like '张%',就建 (age, name) 的复合索引。
复合索引有个 “最左前缀” 原则,比如建了 (a,b,c) 索引,能用上索引的是where a=...where a=... and b=...where a=... and b=... and c=...,但where b=...where a=... and c=...就用不上,这点新手最容易踩坑。

3. 这些情况索引会失效,一定要避开


建了索引却没用上,多半是犯了这些错:
  • 字段类型不匹配,比如字段是 int,查询用where id = '123'(字符串),索引失效;
  • 用 is null/is not null,某些版本 MySQL 对 null 的索引支持不好,尽量用默认值代替 null;
  • 复合索引中前面的字段用了范围查询(>、<、between),后面的字段索引失效,比如where age > 18 and name = '张三',(age, name) 索引只能用到 age 部分。

三、自问自答:实战中常见的优化问题


  • 问:查询数据量很大,怎么优化都慢怎么办?
    可以分表!比如按时间分表,把历史数据分到不同表,只查最近的表;或者按用户 id 分表,每个表数据量变小,查询自然快。
  • 问:索引建了还是慢,可能哪里错了?
    看看索引是不是 “失效” 了,用 explain 检查;或者索引太多,更新数据时维护索引耗时,这时候得删一些没用的索引。
  • 问:小表查询需要建索引吗?
    表数据少于 1 万条,全表扫描可能比走索引还快,因为索引本身也要查,这时候可以不建索引,别浪费空间。

结尾心得


其实查询优化和索引设计,核心就是 “理解 MySQL 怎么干活儿”。你得知道 MySQL 是怎么找数据的,索引是怎么帮它提速的,才能写出高效的语句。兔子哥建议新手多动手用 explain 分析自己的查询,看看哪里慢,再针对性优化。
别一开始就追求复杂技巧,先把基础的 “别用 select *”“复合索引最左前缀” 这些做好,大部分慢查询问题就解决了。多测试不同的写法,对比执行时间,慢慢就有 “优化感” 了。数据库优化是个熟能生巧的活儿,练得多了,你也能一眼看出查询语句的问题,赶紧动手试试吧!有问题随时留言问我呀。

标签: 立竿见影 朋友们

发布评论 0条评论)

  • Refresh code

还木有评论哦,快来抢沙发吧~