你有没有这种感觉哈——明明你写的SQL看着挺带劲的,where写得比语文作文都优雅,结果页面死活加载不出来,一explain,发现是“type = ALL”,rows还几百几千万……这不是优化,这是火葬场,MySQL已经默默给你开追悼会了你知道不。
咱今儿就不走啥“高级教程”那种正经路数了,说人话,一口气给你捋清楚:索引为啥不生效?explain里都看啥?怎么整才叫“靠谱点”的SQL?该说不说,这玩意真得有人带一把,不然容易查着查着把数据库CPU给送走。
一、索引是好东西,但你得用明白了才能叫“优化”
很多兄弟一提“索引”就瞪眼睛:我靠我建了索引啊咋还慢?我寻思着你得掂量掂量,你那个索引是装门面还是能干活。
1. 你以为你建的是索引,其实是废铁
select * from user where left(name, 2) = '张三';
这句咋样?看着人模狗样的对吧?实话告诉你,这特么直接把索引给废了,你在字段上套函数,MySQL压根认不出来,跟你说“我不认这个亲戚”。
你得改成:
select * from user where name like '张三%';
这才像话,name上要是建了索引,MySQL嗖嗖地就给你查出来了。
2. 联合索引你不会用,真不怪MySQL慢
create index idx_user_name_age on user(name, age);
这你建上去了,但查询时你老来一手:
select * from user where age = 18;
抱歉,白建。联合索引是有顺序的,得从name开始查,age在name后面是“附属品”,你不用name这主菜,age单吃没卵用。你得写成:
select * from user where name = '王麻子' and age = 18;
这时候MySQL才心情好一点。
二、Explain 是啥?不是摆设,是你SQL的CT片
你看病都知道拍个片子,那你SQL卡成狗的时候为啥不explain一下?你连它咋走的都不知道,光靠猜,那不是靠玄学干活嘛!
explain select * from user where name = '李四';
一执行,返回一堆字段,别急,咱一条条掰开揉碎说:
1. id(执行顺序)
越大越先执行,多个表join的时候这玩意看得最清楚,谁先谁后一眼就看明白了。
2. select_type(你是个什么玩意)
- SIMPLE:普通查询,没嵌套,没花活;
- PRIMARY:最外层那一层;
- SUBQUERY / DEPENDENT SUBQUERY:子查询,看这个多了说明你SQL有点屎味;
3. table(谁在干活)
这列就跟点名似的,它告诉你这条记录是针对哪个表的。
4. type(重头戏)
- ALL:全表扫,这就跟进村挨家敲门一样;
- index:扫整个索引,勉强凑合;
- range:范围查询,用得多;
- ref、eq_ref、const:这仨是你该追求的理想状态,越往下越高端。
5. key(你到底用哪了个索引)
看着是用了索引,但你得配合type看。有时候MySQL骗你,说“我用索引了”,实际是“我全索引扫一遍”,那不比全表强多少。
6. rows(干了多少活)
查了多少行,越少越香。如果这列一上来就几百万,那你得反思一下你这SQL是不是喂了屎。
7. Extra(一些隐形信息)
你看到“Using filesort”“Using temporary”这俩字,直接给我警觉起来。说明你那SQL还没优化明白。
三、优化场景实操,别光听理论,咱得真刀真枪来点
场景1:子查询屎山
select * from user where id in (select user_id from orders where price > 100);
MySQL一看:哎哟你还嵌套呢,懒得优化你。
优化法:
select u.* from user u join orders o on u.id = o.user_id where o.price > 100;
这种才叫实在点,不光MySQL开心,你CPU也不发烧。
场景2:分页优化,不然查着查着人都没了
select * from user order by id limit 100000, 20;
分页越大越慢是常识你知道不?优化方式就是靠“上一次的ID继续查”:
select * from user where id > 上一页最后一条id limit 20;
这种才叫高效,不然越查越慢,查到后来你就得换台服务器。
总结:别再靠祈祷让SQL跑快了,你得真懂点
这篇文章说白了就是掏心窝子跟你唠嗑——MySQL这活儿啊,它不是靠“建了索引就天下无敌”,也不是靠“执行慢就买台大点的服务器”。真要跑得快,你得一行一行扣,一字段一字段看。
你得知道索引是咋建、咋用、为啥不起作用,得知道Explain里每列是啥意思、哪行能救你命、哪行是坑。
写代码不是在写诗,你不能光图好看。SQL写出来是跑的,不是挂墙上的。
行吧兄弟们,这一篇要是真能帮你少查几千万行,那咱今天就没白叨叨。要是你有那种“我查不动了”“我优化不了”那种屎山SQL——评论甩出来,咱一块儿给它收拾咯。