MySQL性能优化实战:慢查询到毫秒响应全链路突破
|
去年中考那几天,监控大屏突然炸出个红色慢查询,我盯着屏幕上的行数跳了俩小时——平时零点几秒的查询,直接飙到八秒多,关键这破表还就三百万数据,连个全文索引都没有,我原以为随便加个索引就能搞定,结果运维小王冲进来喊:"哥,考试系统要崩了!" 风扇在脚底下转得嗡嗡响,我手抖着敲了条`EXPLAIN`,发现这查询条件根本不走索引——开发写的SQL里,`WHERE`后面跟了个`DATE_FORMAT(create_time, '%Y-%m-%d')`,我当场骂出声:"这他妈不是逼MySQL算日期吗?"小王凑过来看,屏幕反光里他眼镜片闪了下:"哥,这表是不是分区了?"我愣住,分区表?我翻了下表结构,好家伙,`create_time`按年分区,但查询条件被函数一包,分区裁剪直接失效,MySQL得扫全表三百万数据,再算日期,再过滤,能不慢吗? 开发小李这时候端着外卖进来了,凉了的炒饭往桌上一撂:"我早说别用函数,你们非说方便。"我白他一眼:"方便个屁,你写SQL的时候怎么不看看执行计划?"他撇嘴:"我哪知道MySQL这么蠢,函数一包索引就没了?"我气得拍桌子:"这不是蠢,是规则!索引是按字段原值存的,你给字段套个函数,MySQL上哪找对应的索引值去?"
文章配图,仅供参考 窗外天黑了,监控大屏的红色还没消,我盯着那行跳动的SQL,突然想起上周备份策略的事——主库每天全量备份,从库每半小时增量备份,但中考期间数据量暴涨,备份线程和查询线程抢资源,从库延迟从三秒涨到三十秒,主库慢查询一多,从库更跟不上,整个链路都卡住了。我原以为备份策略没问题,结果关键时刻掉链子,这破系统,真是哪哪都埋着雷。小王突然说:"哥,要不把查询条件改了吧?"我愣了下:"怎么改?"他指着屏幕:"把`DATE_FORMAT`去了,直接用`create_time >= '2023-06-01' AND create_time < '2023-06-02'`,这样分区裁剪能生效,索引也能用。"我试了下,`EXPLAIN`结果立马变了,`type`从`ALL`变成`range`,`key`显示用了分区索引,执行时间从八秒掉到零点二秒。我长出一口气:"操,早这么写不就好了?"小李在旁边嘟囔:"我早说了,你们不听。" 但问题还没完——中考期间流量是平时的三倍,这查询虽然快了,可并发一上来,锁竞争又成问题。我翻了下`SHOW ENGINE INNODB STATUS`,发现不少查询在等`SELECT ... FOR UPDATE`的锁,开发小李写的代码里,但凡涉及订单状态更新的,全加了排他锁,可很多操作根本不需要锁,比如查状态、改备注,这些完全可以读已提交隔离级别搞定,非得上`FOR UPDATE`,把锁粒度搞这么大,并发能不卡吗? 我喊小李过来:"你这锁加得也太随意了吧?"他挠头:"我怕数据不一致。"我冷笑:"不一致个屁,你知不知道`FOR UPDATE`会锁行?并发一高,所有查询都得排队,系统能不慢吗?"他小声说:"那...那怎么改?"我指了指代码:"先把不需要锁的查询全去掉`FOR UPDATE`,必须锁的,把锁粒度缩小到字段级,别锁整行。"他点头:"行,我现在改。" 改完再测,锁等待时间从三秒掉到零点一秒,系统吞吐量翻了两倍。我松了口气,转头看监控大屏,红色慢查询终于消失了,取而代之的是一片绿色。小王凑过来:"哥,这就算优化完了?"我摇头:"完个屁,这只是治标,治本得重构表结构——`create_time`按天分区,查询条件别用函数,索引设计要符合查询模式,事务别乱加锁,还有备份策略得调整,主从延迟得监控..."我越说越气,"这破系统,从设计到开发,全是坑,能跑到现在算命大。" 小李在旁边小声说:"哥,午饭还没吃呢。"我低头看了眼表,差三分钟九点,外卖凉透的炒饭还摆在桌上,风扇还在转,窗外彻底黑了。我叹了口气:"吃个屁,先写优化报告,明天领导要看。"小王问:"哥,你觉得这次优化能撑多久?"我盯着屏幕上的绿色指标,想了想说:"优胜劣汰吧——现在快,是因为我们踩了所有坑,知道怎么避;但业务一变,数据量一涨,新坑又会出现,到时候还得再优化。"我顿了顿,"反正MySQL就这样,没有一劳永逸的优化,只有不断踩坑、填坑、再踩坑。" 下一步?我打算把这次优化的过程写成文档,给开发和运维都培训一遍——尤其是索引和锁的使用,别再瞎搞了。至于系统能不能真正稳定,谁知道呢?反正我已经把能做的都做了,剩下的,看命吧。 (编辑:我爱制作网_池州站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |


iOS电商App数据可视化:15年性能优化师让行为数据实时开口
Go建站性能优化与高效存储实战指南
VR开发编译加速与边缘节点性能优化实战
浙公网安备 33038102330577号