今天上班折腾这个搞到晚上9点,记录下来免得后人踩坑

前言

今天项目经理过来说我有一张TAPD单已经挂了一个月了,要我解决免得影响考核。我一看,是首页的数据报表接口速度过慢超时。

这个问题很早就提给我了,那个时候因为其他任务过于着急只能先挂起。现在要过考核所以只能尽快解决。

分析

首先查询代码中的数据表名称,前往正式环境的 MySQL 种查看,不看不知道一看吓一跳,2500万行单表,没有索引。 所以解决方法肯定是先加索引。这里我就被坑了,代码中使用了单独的函数生成 where 子句,我尝试把 where 子句中的值加入索引,结果没有效果。

然后我就尝试打印最后生成的 SQL 语句。结果得到了这样的白痴语句 WHERE a = ? AND b between ? AND ? AND c = ?

回想起来之前看过的面经提到,SQL的联合索引在范围检索的时候会慢很多,所以正确的办法应该把所有准确匹配的先放在最左边,MySQL 的联合索引会根据最左原则匹配使用索引。

解决

首先,要调整代码中的 SQL 顺序,使准确匹配在最左侧。WHERE a = ? AND c = ? AND b BETWEEN ? AND ?

然后,需要在数据库里增加索引 ALTER TABLE table_name ADD INDEX index_name (a,c,b);

添加索引这个事,耗时足足4分钟。

效果和总结

优化前:18秒,远远超出平台规定的5秒限制,只能稍等一会重新请求,第二次会打到缓存上所以说一直这么对付着。

优化后:800ms,相比之前是飞一样的进步。

总结:MySQL的非破坏性大表优化就是加索引,加索引最重要的就是要检查是否会有条件打断你的索引,一旦索引条件被破坏,那么 MySQL 只能全力扫表。 扫表的话,2500万的表确实要扫一阵。我们的机器还是公司内部云的那种MySQL,底层有SSD加持,要是HDD怕是更烂。

当然如果数据表再大的话,就需要根据业务逻辑进行分表拆表了。倾向于根据业务逻辑选择进行分表,如果表还大的话,就需要根据时间进行分表了,那样要改动的逻辑就会很多了。