热点

sql语句优化5种方式

时间:2010-12-5 17:23:32  作者:休闲   来源:休闲  查看:  评论:0
内容摘要:一条SQL跑三秒,加了个索引变成三十毫秒。这种事我遇到过太多次。多数人以为SQL优化是DBA的活儿,其实几条简单习惯就能让性能翻倍,下面这五种方式,是我从一堆烂SQL里总结出来的。 第一,别用SELE

一条SQL跑三秒,句优加了个索引变成三十毫秒。化种这种事我遇到过太多次。句优多数人以为SQL优化是化种DBA的活儿,其实几条简单习惯就能让性能翻倍,句优下面这五种方式,化种是句优我从一堆烂SQL里总结出来的。

第一,化种别用SELECT *,句优哪怕你嫌打字麻烦。化种有一次我看同事的句优代码,查一张二十个字段的化种表,业务只需要三个字段。句优他图省事写了星号,化种结果这表数据量到了五百万行,句优每次查询要把所有字段读出来,I/O开销直接拖垮了接口。改成明确字段后,响应时间从八百毫秒降到一百二。MySQL里星号还会让覆盖索引失效——明明索引里有你要的数据,非得多回一次表,这亏吃得不值。

第二,WHERE子句里的函数和隐式转换是性能杀手。比如你写了WHERE DATE(create_time) = '2024-01-01',这会让create_time上的索引完全失效,因为数据库得对每一行都执行DATE函数才能比较。正确做法是WHERE create_time >= '2024-01-01' AND create_time < '2024-01-02'。还有个隐蔽的坑:字段是varchar,你传了数字,MySQL会先把字段转成数字再比,索引照样废。这种问题排查起来最气人,因为SQL看着挺正常。

第三,LIMIT分页越深越慢,得换思路。典型的翻页写法LIMIT 100000, 20,MySQL得先扫十万行再扔掉前十万行。我自己项目里就踩过,后台管理列表翻到几百页时,页面直接卡死。后来改成记录上一页最后一条的ID,用WHERE id > 上次最大值 ORDER BY id LIMIT 20,速度从两秒变成几十毫秒。如果业务非要跳页,那就用延迟关联——先查主键再回表,别让大字段跟着一起扫。

第四,JOIN别超过三张表,而且关联字段必须有索引。这不是死规矩,是经验。多表JOIN时,MySQL的优化器经常选错驱动表,尤其是关联字段没索引的情况下,要产生临时表和文件排序。我见过最离谱的一个查询,六张表JOIN,跑了三十秒。拆成两个查询,中间用结果集缓存,总耗时不到一秒。另外,EXPLAIN里看到Using temporary; Using filesort,基本就是SQL写歪了,要么改JOIN顺序,要么加合适的复合索引。

第五,OR条件改成UNION,或者用IN代替。OR在MySQL里经常导致索引失效,比如WHERE status = 1 OR status = 2,优化器有时候会放弃索引全表扫。改成WHERE status IN (1, 2)就好很多。但如果是不同字段的OR,比如WHERE name = 'x' OR age = 20,那大概率得全表扫,这种时候拆成两个查询用UNION ALL合并,反而更快。注意是UNION ALL,不是UNION——后者会去重,多一次排序开销。

这些优化方法,说穿了就是让MySQL少干活。别信什么“数据库会自动优化”的鬼话,它再聪明也猜不透你的业务意图。写完SQL花十秒看一眼执行计划,比上线后半夜被叫起来修强得多。对了,最后补一句——加索引不是万能药,写错查询逻辑,索引再多也白搭。

最近更新
热门排行
copyright © 2026 powered by 力不从心网   sitemap