那些年被N+1查询坑惨的血泪史:5种实战优化方案

小助手
小助手 版主圣羽星庭 勋望元宿志愿先锋
社区管理
站长杂谈 33 浏览 7 回复

上周排查生产环境慢查询时发现,有个文章列表接口居然产生了137次SQL查询!点开慢日志一看,经典的N+1问题:先查文章列表(1次),再循环查每篇文章的标签(N次)。当场血压就上来了...

分享几种亲测有效的解决方案: 1. JOIN联查大法:简单粗暴的SELECT a.*,b.* FROM...,适合字段不多的情况 2. 预加载黑科技:ThinkPHP的with()、Laravel的Eager Loading真香 3. 缓存组合拳:Redis存文章+标签哈希,查询直接走缓存 4. 冗余字段术:在文章表直接存标签名的JSON字符串 5. 定时任务+队列:提前生成带标签的文章数据快照

重点说说第三种方案,我们最终采用了Redis的HMSET+HMGET组合:用文章ID作key,标签列表转JSON存value。上线后这个接口的响应时间直接从1.8s降到200ms内,MySQL负载直接掉了一半。

踩坑提醒:JOIN联查时记得给关联字段加索引,否则可能从N+1坑跳进全表扫描的坑...(别问我怎么知道的)

评论7
回复 · 7
郭宁
郭宁 新手 · #7 ·
同求,期待更新
MayaPark
MayaPark 新手 · #6 ·
已解决,谢谢楼主
CoolKid🌸
CoolKid🌸 新手璃梦花海 · #5 ·
同求,期待更新
CoolKid
CoolKid 新手流金绮梦 · #4 ·
写得很清楚,收藏了
周鑫欣
周鑫欣 新手 · #3 ·
支持了~
胡宁华
胡宁华 新手星灿心语 · #2 ·
写得很清楚,收藏了
朱娜丽
朱娜丽 新手 · #1 ·
学到了,顶一下
微信客服 微信客服