您现在的位置是:探索 >>正文
sql优化常用的15种方法
探索315人已围观
简介上周帮同事看一条查询,三张表关联,跑了47秒。我看了一眼执行计划,驱动表选错了,中间结果集被放大到几百万行。加了个复合索引,调整了连接顺序,降到0.3秒。这种事我每个月都会遇到几次,SQL优化的收益有 ...
上周帮同事看一条查询,优用三张表关联,化常跑了47秒。种方我看了一眼执行计划,优用驱动表选错了,化常中间结果集被放大到几百万行。种方加了个复合索引,优用调整了连接顺序,化常降到0.3秒。种方这种事我每个月都会遇到几次,优用SQL优化的化常收益有时候就是这么夸张。
下面这些方法,种方是优用我这些年踩坑踩出来的,按实际使用频率排列,化常不按教科书目录。种方
1. 先看执行计划,别猜
EXPLAIN是起点。MySQL用EXPLAIN,PostgreSQL用EXPLAIN ANALYZE,Oracle看AUTOTRACE。重点盯三样:type列(有没有全表扫描)、rows列(预估行数是否离谱)、Extra列(有没有Using filesort、Using temporary)。很多人跳过这步直接改SQL,等于蒙着眼睛修车。
2. 索引不是越多越好
见过一张订单表建了12个索引,写入性能惨不忍睹。每个索引都要占空间、维护B+树。原则是:高频查询的WHERE、ORDER BY、JOIN字段才建,低区分度的列(比如性别)单独建索引没意义。
3. 复合索引讲顺序
(a,b,c)和(c,b,a)是两回事。最左前缀原则大家都知道,但实际写SQL时经常忘。WHERE b=1 AND c=2用不上(a,b,c)索引,因为跳过了a。范围查询后面的字段也失效——WHERE a=1 AND b>2 AND c=3,c用不到索引。
4. 别在索引列上做运算
WHERE DATE(create_time) = '2024-01-01' 这种写法直接废掉索引。改成 WHERE create_time >= '2024-01-01' AND create_time < '2024-01-02'。函数、类型转换、表达式,只要包在索引列外面,索引就失效。
5. 用JOIN代替子查询
相关子查询在旧版MySQL里会逐行执行,性能灾难。能改写成JOIN就改。不过PostgreSQL和MySQL 8.0对子查询优化好了很多,具体看执行计划再决定。
6. 小表驱动大表
JOIN的时候让小结果集做驱动表。IN和EXISTS的选择也是这个逻辑:外层小用IN,内层小用EXISTS。听起来简单,但优化器有时候会选错,必要时用STRAIGHT_JOIN强制指定顺序。
7. 分页查询别用大OFFSET
LIMIT 1000000, 20 会扫描前100万行再丢掉。改成游标方式:WHERE id > 上次最大id LIMIT 20。或者用延迟关联,先在索引上拿到主键再回表。
8. 只查需要的列
SELECT * 的问题不只是网络传输。如果查询能走覆盖索引,只取必要列就能避免回表,性能差好几倍。我见过有人把SELECT * 改成具体列,查询从2秒降到50毫秒。
9. 批量操作代替循环单条
循环里跑INSERT,每次一个事务,一万条数据能跑几分钟。改成批量INSERT,每批500到1000条,几秒钟搞定。UPDATE和DELETE同理。
10. 合理使用临时表
复杂查询拆成几步,中间结果放临时表,比一条巨型SQL好维护也好优化。尤其是多个大表JOIN再聚合的场景,临时表反而更快。
11. 注意隐式类型转换
user_id是varchar,你写WHERE user_id = 12345,MySQL会做隐式转换,索引直接失效。这种坑很隐蔽,执行计划里看type变成ALL就要警惕。
12. OR改UNION
WHERE a=1 OR b=2,如果a和b都有索引,优化器可能不走索引。改成两个查询UNION ALL,各自走索引再合并,通常更快。
13. 分区表处理大表
单表过亿行,加索引也救不了全表扫描。按时间或范围分区,查询时能裁剪掉无关分区。不过分区键选不好反而添乱,要结合查询模式来定。
14. 统计信息要更新
优化器靠统计信息选执行计划。数据变化大了统计信息过期,执行计划就跑偏。MySQL的ANALYZE TABLE,PostgreSQL的VACUUM ANALYZE,定期跑一下。
15. 读写分离和缓存
有些查询优化到头也就那样了,不如加一层Redis缓存,或者把读请求分流到从库。这不是SQL层面的优化,但解决实际问题时经常是最有效的手段。
最后说一句:别背规则,看执行计划。同一条SQL在不同数据量、不同版本下表现可能完全相反。我见过把索引删掉反而变快的案例——因为优化器选了错误的索引。工具是死的,数据是活的。
Tags:
上一篇:爱聊软件骗局
下一篇:湖北省纤维检验局荆州分局官网
相关文章
市场渗透率计算公式
探索市场渗透率=已购买该产品的顾客数÷目标市场总顾客数)×100%。这个公式看着简单,真正用起来却藏着不少坑。我见过太多创业者拿着这个数字到处路演,张口就是“我们的渗透率已经达到15%”,但细问之下,分母 ...
【探索】
阅读更多唯品会首页官网
探索唯品会首页官网一打开,满屏都是红色的折扣标签,像过年一样热闹。但你要是以为这只是个普通的打折网站,那就错了。 我盯着那个搜索框看了半天,它旁边挂着"特卖"两个字。这词儿用得妙,比"促销"听起来高级,比 ...
【探索】
阅读更多北京各大超市管道清洗
探索北京东四环那家永辉超市,凌晨两点半,我跟着清洗队进去的时候,地砖上还映着日光灯惨白的倒影。带队的老师傅姓周,五十来岁,手里攥着根一米来长的不锈钢探针,蹲在生鲜区排水沟边上,半天没动弹。突然他“啧”了一 ...
【探索】
阅读更多