SQL调优的“二八法则”:用20%的投入解决80%的慢查询
大家好我是小耶写功课只是为了我踩过的坑你们别再踩了你有没有过这种经历花了一下午把一条跑30秒的SQL优化到0.5秒成就感满满结果业务方说“没感觉啊”。而你隔壁同事随手优化了一条0.3秒的SQL业务方反而说“快了好多”。这不是你的优化技术不行是你优化的对象选错了。有一条SQL每天跑1次每次30秒日消耗30秒。另一条SQL每天跑10万次每次0.3秒日消耗3万秒。你把第一条从30秒优化到0.5秒节省了29.5秒。你把第二条从0.3秒优化到0.05秒节省了2.5万秒。这就是“二八法则”在SQL优化中的体现——20%的投入找到正确的那条SQL决定了80%的收益整体性能提升。一、先算账再动手从“最慢的SQL”到“总消耗最大的SQL”大部分人的优化逻辑是打开慢查询日志按执行时间排序把最慢的那条拎出来优化。这个逻辑有两个问题问题一慢查询日志的阈值可能设高了。如果long_query_time10.3秒的SQL根本不会出现在日志里。但每秒执行100次日消耗2.6万秒的SQL它才是真正的性能杀手——只是从来没被你看到过。问题二忽略频率。一条跑得慢但很少执行的SQL和一条跑得快但每秒执行100次的SQL后者的总消耗可能比前者大几个数量级。正确的做法是先算总消耗再排序。总消耗 单次执行时间 × 执行频率把这条公式记在脑子里。下次优化前先找出总消耗最大的前10条SQL而不是单次执行最慢的那几条。你会发现排在前面的往往是那些你以为“很快”的SQL——只是因为它们跑得太频繁了。怎么找到总消耗最大的SQL方法一用pt-query-digest分析慢查询日志按“总响应时间”排序输出。方法二开启performance_schema查询events_statements_summary_by_digest表直接获得每条SQL的累计执行时间和执行次数算平均值和总消耗。二、建立优化优先级矩阵四象限法把SQL按“单次耗时”和“执行频率”两个维度划分画一个四象限象限单次耗时执行频率优化优先级策略 第一象限高高最高立即优化收益最大 第二象限高低中等有空优化收益尚可 第三象限低高高值得优化积少成多 第四象限低低最低暂不处理收益太低第一象限的SQL是“双高”——单次慢、频率高。这种SQL是性能毒瘤优化一条就能让整个系统脱胎换骨。如果你发现一条SQL每次跑3秒、每秒执行50次日消耗就是1296万秒——别犹豫放下一切优化它。第三象限的SQL是“高频低耗”——单次看起来很快0.1秒但频率极高每秒数百次。这种SQL容易被忽略但总消耗可能比第一象限还大。优化思路是“减少执行次数”而不是“加快单次速度”——比如加缓存、合并查询、改写业务逻辑避免重复查询。三、实战案例一条“很快但很忙”的SQL某电商系统用户反馈“加购物车变慢了”。慢查询日志里没有一条超过1秒的SQL。用performance_schema查总消耗排序发现排名第一的是一条SELECT user_id, name, avatar FROM users WHERE id ?平均执行时间0.05秒每秒执行了300次。日消耗0.05 × 300 × 86400 129.6万秒。根因加购物车时每次都要查一遍用户信息。但用户信息基本不变根本不需要每次都查数据库。优化方案在Redis里缓存用户信息缓存时间5分钟。从查询到命中缓存应用层做了个简单的改造加了几行代码。效果用户信息查询的数据库请求从每秒300次降到几乎为0加购物车接口响应时间从200ms降到80ms业务方说“流畅了”。这条SQL单次只有0.05秒如果按“最慢的SQL”去排它永远不会被注意到。但按总消耗排它排第一。四、建立常态化监控机制让数据告诉你该优化什么不要等业务方投诉才去看慢查询。建立常态化的监控机制开启performance_schema记录所有SQL的累计执行数据每周跑一次总消耗排行找出本周总消耗TOP 10对比上周数据发现新出现的“高频低效”SQL建立优化清单按四象限分类确定本周优化目标每周优化3条总消耗最大的SQL坚持一个月系统整体性能会有肉眼可见的提升——而且你会发现真正需要动大手术的SQL其实不多大部分都是这种“单个不慢但总量惊人”的SQL。五、总结SQL优化的核心不是“技术有多深”而是“优先级对不对”。不要只看单次耗时要看总消耗耗时×频率不要只优化最慢的要优化总消耗最大的用四象限法给SQL排优先级建立常态化监控让数据告诉你该做什么把精力和时间花在对的地方用最少的投入撬动最大的收益——这才是高效DBA和普通DBA的核心区别。下次打开慢查询日志先别急着看最慢的那条问问自己“总消耗最大的那条SQL我找到了吗”小耶在手SQL 不愁还有什么想了解的欢迎留言小耶一定知无不言言无不尽……我们下次见~