一个客户的管理后台某天开始诡异变卡:任何人一登录首页,全公司系统跟着慢。查了服务器没崩、网络正常,最后揪出真凶——首页那条汇总查询,五十万行的表全表扫描,每扫一次几秒钟,几个人同时打开就排队堵死。后端系统开发的数据库优化,十次里八次是索引的账。
先让慢查询现形
优化前得知道谁在慢,工具现成:数据库的慢查询日志打开,把超过一秒的查询全记下来,跑一两天,问题清单自动浮出来。再配一个explain看执行计划,某条SQL扫了多少行、有没有走到索引,一目了然。这两步不需要多高深的功力,却多数项目根本没开,慢着慢着大家就习惯了,把病态当常态。
索引为什么用不上
- 查询条件里的字段压根没建索引,全表扫描,这是最常见的一种;
- 字段上包了函数:对日期字段套一层转换再比较,索引直接失效,改成范围查询就能走索引;
- 联合索引顺序不对:索引按第一列排序,查询却只筛第二列,等于白建,顺序要按最常用的条件放前面。
把那几条慢查询对症加索引后,首页加载从四秒回到零点三秒,客户以为我们做了什么大手术,其实改了几行建表语句。索引优化的回报率,在性能手段里排第一,也是后端系统开发验收时最该盯的一项。
加索引也有讲究。大表在线上加索引可能锁表,几十万行以内无所谓,几百万行的表要挑业务低峰操作,或者用在线变更工具。索引也不是越多越好:每加一个索引,写入时都要多维护一棵树,订单这种高频写入的表,索引堆太多插入速度肉眼可见地变慢,常用的查询路径配齐就收手。
还有一类慢不是索引能救的:一次性查几十万行往页面上怼、循环里逐条查库这种写法问题,得改代码。所以看慢查询日志要连着代码一起看,工具和写法两头都得顾,单靠加索引救不了烂SQL。
把这事交给谁管
优化不是一劳永逸的,数据量在涨,今年没事的查询明年可能就慢了。慢查询日志常开、每周有人看一眼,才是长久之计,这条该写进后端系统开发的运维约定。运维上也可以设个阈值告警,慢查询数量突增就提醒。
两条建议:验收系统时要求开启慢查询日志,并约定超过一秒的查询为零或给出解释;系统用了两年以上、明显变慢的,先请比格网络这类团队做一次数据库体检,多数情况下不用换服务器不用换数据库,几百块的优化就能还你一个流畅的后台。