做MySQL性能调优三年了,踩了很多坑,也积累了一些经验,今天,就,来,分享,一下,我,这,三年,来,做,MySQL,性能,调优,明白,的,一些,道理,希望,能,给,正在,做,数据库,优化,的,朋友,一些,参考,和,启发。

刚,入行,的,时候,我,对,MySQL,性能,调优,的,理解,很,肤浅,觉得,调优,就是,加,索引,改,配置,但是,做,了,三年,之后,我,才,发现,MySQL,性能,调优,是,一门,很深,的,学问,涉及,SQL,优化,索引,设计,配置,优化,架构,设计,等等,很多,方面,而且,很多,道理,是,踩,了,坑,之后,才,明白,的。

今天,这篇,文章,就,来,好好,聊聊,我,这,三年,来,做,MySQL,性能,调优,明白,的,那些,道理。

一、性能调优不是加索引那么简单

先说说,第一个,道理,性能,调优,不是,加,索引,那么,简单。

刚,入行,的,时候,我,对,MySQL,性能,调优,的,理解,很,肤浅,觉得,SQL,慢,了,就,加,索引,加,了,索引,就,能,变快,但是,实际,做,了,之后,才,发现,不是,这么,简单。

有,一次,线上,有,个,SQL,很慢,我,看,了,一下,没有,索引,就,加,了,个,索引,结果,加,了,索引,之后,SQL,确实,变快,了,但是,过,了,几天,又,慢,了,我,很,纳闷,后来,查,了,一下,才,发现,是,因为,数据,量,增长,了,索引,的,区分度,变,低,了,而且,SQL,的,写法,也,有,问题,加,了,索引,也,没,用,对,最后,还是,通过,改写,SQL,加上,联合,索引,才,解决,了,问题。

那,时候,我,才,明白,性能,调优,不是,加,索引,那么,简单,加,索引,只是,其中,的,一个,手段,而且,加,索引,也,不是,随便,加,的,要,考虑,索引,的,区分度,联合,索引,的,顺序,覆盖,索引,等等,很多,因素,加,错,了,索引,不仅,不能,提高,性能,还,可能,降低,性能,因为,索引,也是,要,占,空间,的,而且,写,操作,的,时候,还要,维护,索引,会,降低,写,性能。

而且,性能,调优,也,不,只是,SQL,和,索引,的,问题,还有,配置,优化,架构,设计,等等,很多,方面,比如,MySQL,的,配置,参数,是不是,合理,缓存,是不是,够,大,连接,数,是不是,够,事务,隔离,级别,是不是,合适,等等,这些,都会,影响,性能,还有,架构,方面,是,不是,需要,读写,分离,是不是,需要,分库,分表,是不是,需要,加,缓存,等等,这些,都,是,性能,调优,需要,考虑,的。

所以,性能,调优,是,一个,系统,工程,不是,加,索引,那么,简单,要,从,多个,方面,综合,考虑,才能,真正,解决,性能,问题。

二、先搞清楚问题再调优

第二个,道理,先,搞,清楚,问题,再,调优,不要,盲目,调优。

刚,入行,的,时候,我,一,遇到,性能,问题,就,着急,去,改,这个,改,那个,加,索引,改,配置,但是,往往,改,了,半天,问题,还,没,解决,甚至,越,改,越,糟,后来,我,才,明白,调优,之前,一定,要,先,搞,清楚,问题,到底,是什么,原因,导致,的,然后,再,针对性,地,调优,不要,盲目,调优。

有,一次,线上,数据库,CPU,很,高,我,一,看,CPU,高,就,以为,是,SQL,慢,导致,的,就,去,查,慢,查询,加,索引,忙,了,半天,CPU,还是,高,后来,冷静,下来,仔细,查,了,一下,才,发现,不是,SQL,的,问题,是,因为,有,个,定时,任务,在,全表,扫描,做,数据,统计,而且,这个,任务,还,开,了,很多,线程,同时,跑,导致,CPU,很,高,最后,把,这个,定时,任务,优化,了,改成,增量,统计,而且,限制,了,并发,数,CPU,就,降,下来,了。

那,时候,我,才,明白,调优,之前,一定,要,先,定位,问题,搞,清楚,到底,是什么,原因,导致,的,性能,问题,然后,再,针对性,地,解决,不要,一,上来,就,盲目,调优,那样,不仅,解决,不,了,问题,还,可能,浪费,时间,甚至,引入,新,的,问题。

定位,问题,的,方法,有,很多,比如,看,MySQL,的,慢,查询,日志,看,哪些,SQL,执行,慢,看,show processlist,看,当前,有,哪些,线程,在,运行,看,explain,看,SQL,的,执行,计划,看,MySQL,的,状态,变量,比如,QPS,TPS,连接,数,缓存,命中率,等等,还有,看,服务器,的,CPU,内存,IO,网络,等等,指标,综合,分析,才能,定位,到,真正,的,问题。

而且,定位,问题,的,时候,要,有,耐心,不要,着急,慢慢,分析,一步步,排查,才能,找到,根本,原因,不要,只,看,表面,现象,就,下,结论,那样,很,容易,误判。

三、索引不是越多越好

第三个,道理,索引,不是,越多,越好。

刚,入行,的,时候,我,以为,索引,越,多,越,好,每个,字段,都,加,索引,这样,查询,就,都,能,走,索引,了,但是,后来,才,发现,不是,这样,的,索引,不是,越多,越好,太多,的,索引,反而,会,降低,性能。

有,一次,我,给,一个,表,加,了,很多,索引,几乎,每个,查询,条件,的,字段,都,加,了,索引,结果,查询,确实,变快,了,但是,写,操作,变,慢,了,很多,因为,每次,插入,和,更新,的,时候,都,要,维护,所有,的,索引,写,性能,下降,很,明显,而且,索引,也,占,了,很多,存储空间,后来,我,把,一些,没用,的,索引,删掉,了,写,性能,就,恢复,了,查询,性能,也,没,怎么,受,影响。

那,时候,我,才,明白,索引,不是,越多,越好,要,合理,地,建,索引,只,给,需要,的,字段,建,索引,而且,要,考虑,索引,的,使用,效率,不要,建,没用,的,索引。

建,索引,的,时候,要,注意,几个,原则,第一,区分度,高,的,字段,适合,建,索引,区分度,低,的,字段,比如,性别,状态,等等,不,适合,单独,建,索引,因为,区分度,太低,走,索引,还,不如,全表,扫描,快;第二,联合,索引,要,注意,顺序,把,区分度,高,的,字段,放,前面,把,常用,的,查询,条件,放,前面,遵循,最左,前缀,原则;第三,尽量,建,覆盖,索引,把,查询,需要,的,字段,都,放,在,索引,里,这样,就,不用,回表,查询,性能,更,好;第四,不要,给,更新,频繁,的,字段,建,太多,索引,因为,更新,的,时候,要,维护,索引,会,降低,写,性能;第五,定期,检查,索引,把,没用,的,索引,删掉,节省,空间,也,提高,写,性能。

而且,建,索引,之前,要,先,分析,查询,场景,看,哪些,查询,需要,索引,然后,针对性,地,建,索引,不要,盲目,地,每个,字段,都,建,索引,那样,只会,适得其反。

四、SQL写法很重要

第四个,道理,SQL,写法,很,重要,很多,性能,问题,都是,SQL,写,得,不好,导致,的。

刚,入行,的,时候,我,写,SQL,很,随意,只要,能,查出,数据,就行,不,注意,写法,但是,后来,才,发现,SQL,的,写法,对,性能,影响,很,大,同样,的,需求,不同,的,写法,性能,可能,差,几倍,甚至,几十倍。

有,一次,线上,有,个,SQL,很慢,我,看,了,一下,SQL,是,这样,写,的,select * from table where name like '%xxx%',而且,表,数据,量,很,大,这个,SQL,全表,扫描,很慢,后来,我,把,like,改成,了,全文,索引,或者,用,搜索引擎,来,做,模糊,查询,性能,就,提升,了,很多。

还有,一次,有,个,SQL,用,了,select ,查,了,很多,不需要,的,字段,而且,这些,字段,里,有,大,文本,字段,导致,查询,很慢,而且,网络,传输,也,慢,后来,把,select ,改成,只,查,需要,的,字段,性能,就,提升,了,很多。

还有,很多,SQL,写法,的,问题,比如,在,索引,字段,上,用,函数,或者,运算,导致,索引,失效,比如,where date(createtime) = '2019-09-30',这样,就,用,不,了,createtime,的,索引,要,改成,where createtime >= '2019-09-30' and createtime < '2019-10-01',才能,走,索引;还有,用,or,连接,多个,条件,如果,其中,一个,条件,没有,索引,就,会,全表,扫描,要,改成,union,或者,给,所有,条件,都,加,索引;还有,深,分页,问题,limit 100000, 10,会,扫描,很多,数据,很慢,要,改成,子查询,或者,延迟,关联,优化,等等。

这些,都是,常见,的,SQL,写法,问题,很多,性能,问题,都是,因为,SQL,写,得,不好,导致,的,所以,写,SQL,的,时候,一定,要,注意,写法,要,考虑,性能,不要,只,求,能,查出,数据,就行。

而且,写完,SQL,之后,要,用,explain,看,一下,执行,计划,看,有没有,走,索引,扫描,的,行数,多,不多,等等,确保,SQL,的,性能,是,好,的,不要,等,线上,出,了,问题,才,来,优化。

五、配置优化不能盲目调参数

第五个,道理,配置,优化,不能,盲目,调,参数,要,根据,实际,情况,来。

刚,入行,的,时候,我,看,了,一些,MySQL,调优,的,文章,就,照着,文章,里,的,参数,去,改,配置,比如,把,innodbbufferpoolsize,设,成,物理,内存,的,80%,把,maxconnections,设,得,很,大,等等,但是,后来,才,发现,不是,所有,参数,都,适合,所有,场景,盲目,调,参数,可能,会,出,问题。

有,一次,我,把,maxconnections,设,得,很,大,觉得,连接,数,越,大,越,能,支持,更,多,并发,但是,后来,线上,出,了,问题,数据库,内存,不够,用,了,因为,每个,连接,都,要,占用,一定,的,内存,连接,数,太,大,内存,占用,就,很,大,而且,连接,数,太,大,也,会,导致,CPU,上下文,切换,频繁,性能,反而,下降,后来,把,maxconnections,调,到,合理,的,值,问题,就,解决,了。

还有,一次,我,把,innodbbufferpoolsize,设,得,很,大,占,了,物理,内存,的,80%,结果,系统,的,其他,进程,没有,足够,的,内存,用,了,导致,系统,很,卡,而且,还,触发,了,swap,性能,下降,很,明显,后来,把,innodbbufferpoolsize,调,到,合理,的,值,给,系统,留,够,内存,问题,就,解决,了。

那,时候,我,才,明白,配置,优化,不能,盲目,调,参数,要,根据,服务器,的,配置,和,业务,的,实际,情况,来,调,不同,的,场景,参数,设置,也,不,一样,没有,万能,的,参数,配置,要,具体,问题,具体,分析。

调,配置,的,时候,要,注意,几个,原则,第一,先,了解,每个,参数,的,含义,和,作用,不要,盲目,照着,别人,的,配置,改;第二,根据,服务器,的,硬件,配置,来,调,比如,内存,大,的话,innodbbufferpoolsize,可以,设,大,一些,CPU,核数,多,的话,innodbthread_concurrency,可以,设,大,一些;第三,根据,业务,特点,来,调,比如,读,多,写,少,的,业务,可以,把,缓存,设,大,一些,写,多,的,业务,要,注意,事务,和,日志,的,配置;第四,调,参数,的,时候,要,一个,一个,调,调,完,观察,效果,不要,一次,改,很多,参数,那样,出,了,问题,不,知道,是,哪个,参数,导致,的;第五,调,参数,之前,要,备份,配置,文件,万一,调,错,了,还,能,恢复。

而且,配置,优化,只是,性能,调优,的,一个,方面,不要,把,所有,希望,都,寄托,在,配置,优化,上,很多,性能,问题,还是,要,从,SQL,和,索引,入手,配置,优化,只是,辅助,手段。

六、架构优化比SQL优化更重要

第六个,道理,架构,优化,比,SQL,优化,更,重要,当,数据,量,大,到,一定,程度,SQL,优化,的,效果,就,有限,了,需要,从,架构,层面,优化。

刚,入行,的,时候,我,觉得,性能,问题,都,能,通过,SQL,优化,和,加,索引,解决,但是,后来,才,发现,当,数据,量,大,到,一定,程度,比如,单表,几千万,甚至,上亿,数据,SQL,优化,的,效果,就,很,有限,了,这,时候,就,需要,从,架构,层面,优化。

有,一次,我们,有,个,表,数据,量,增长,很,快,很快,就,到,了,几千万,数据,虽然,SQL,都,优化,了,索引,也,加,了,但是,查询,还是,越来越,慢,因为,数据,量,太,大,了,索引,也,很,大,查询,的,时候,要,扫描,很多,索引,节点,还是,慢,后来,我们,做,了,分库,分表,把,一个,大表,拆,成,多个,小表,每个,表,数据,量,小,了,查询,就,快,了,很多。

还有,一次,我们,的,数据库,读,压力,很,大,主库,扛,不住,了,虽然,SQL,都,优化,了,但是,读,请求,太,多,主库,还是,扛,不住,后来,我们,做,了,读写,分离,加,了,几个,从库,读,请求,都,走,从库,主库,只,处理,写,请求,压力,就,小,了,很多,性能,也,提升,了。

还有,缓存,也,很,重要,很多,读,请求,其实,不用,每次,都,查,数据库,可以,加,缓存,比如,Redis,把,热点,数据,放,缓存,里,读,请求,先,查,缓存,缓存,没有,再,查,数据库,这样,能,大大,减轻,数据库,的,读,压力,性能,也,能,提升,很多。

这些,都是,架构,层面,的,优化,当,数据,量,和,并发,量,大,到,一定,程度,架构,优化,比,SQL,优化,更,有效,也,更,重要,因为,SQL,优化,是,在,单库,单表,的,基础,上,优化,有,瓶颈,而,架构,优化,是,通过,分布式,的,方式,突破,单机,的,瓶颈,能,支持,更,大,的,数据,量,和,并发,量。

当然,架构,优化,也,不是,随便,做,的,要,根据,业务,的,实际,情况,来,比如,数据,量,不,大,的话,就,不用,分库,分表,不然,只会,增加,复杂度,读,压力,不,大,的话,就,不用,读写,分离,不然,也,会,增加,复杂度,架构,优化,要,在,需要,的,时候,才,做,不要,过度,设计。

七、性能调优要有度量

第七个,道理,性能,调优,要,有,度量,不要,凭,感觉,调优。

刚,入行,的,时候,我,调优,都是,凭,感觉,觉得,这样,改,应该,会,变快,就,改,了,但是,改,完,也,不,知道,到底,有,没有,效果,效果,有,多大,后来,我,才,明白,性能,调优,要,有,度量,要,用,数据,说话,不要,凭,感觉。

调优,之前,要,先,测量,一下,当前,的,性能,是,什么样,的,比如,SQL,的,执行,时间,是,多少,数据库,的,QPS,是,多少,响应,时间,是,多少,CPU,内存,IO,的,使用率,是,多少,等等,有,了,基准,数据,之后,再,调优,调,完,之后,再,测量,一下,看,性能,有,没有,提升,提升,了,多少,这样,才,能,知道,调优,有,没有,效果,效果,有,多大。

而且,调优,的,时候,要,一个,一个,改,改,完,一个,就,测量,一下,看,效果,怎么样,不要,一次,改,很多,东西,那样,出,了,问题,不,知道,是,哪个,改动,导致,的,也,不,知道,哪个,改动,有效,哪个,没,效。

还有,测量,的,时候,要,注意,环境,要,一致,比如,在,测试,环境,测量,的,结果,和,生产,环境,可能,不一样,因为,数据,量,和,并发,量,不一样,所以,最好,在,和,生产,环境,差不多,的,环境,测量,或者,直接,在,生产,环境,测量,但是,要,注意,不要,影响,生产,业务。

而且,测量,的,时候,要,多,测,几次,取,平均值,因为,单次,测量,可能,有,偶然性,不,准确,多,测,几次,取,平均值,更,准确。

总之,性能,调优,要,有,度量,用,数据,说话,不要,凭,感觉,这样,才能,知道,调优,有,没有,效果,也,能,避免,盲目,调优。

八、不要过早优化

第八个,道理,不要,过早,优化,优化,要,在,需要,的,时候,才,做。

刚,入行,的,时候,我,很,喜欢,提前,优化,比如,表,还,没,多少,数据,就,开始,考虑,分库,分表,SQL,还,不,慢,就,开始,各种,优化,但是,后来,才,发现,过早,优化,是,没有,必要,的,而且,可能,会,增加,复杂度,浪费,时间。

有,一次,我,做,一个,项目,表,才,几万,数据,我,就,开始,考虑,分库,分表,觉得,以后,数据,量,会,大,提前,做,了,以后,就,不用,改,了,结果,分库,分表,做,了,很,久,增加,了,很多,复杂度,但是,项目,上线,之后,数据,量,一直,没,怎么,增长,几万,数据,根本,不,需要,分库,分表,白,白,浪费,了,很多,时间,和,精力,而且,分库,分表,之后,很多,操作,都,变,复杂,了,维护,成本,也,高,了,很,不,划算。

那,时候,我,才,明白,不要,过早,优化,优化,要,在,真正,需要,的,时候,才,做,过早,优化,不仅,浪费,时间,和,精力,还,可能,增加,系统,的,复杂度,得不偿失。

当然,也,不是,说,完全,不,考虑,未来,的,扩展,在,设计,的,时候,可以,适当,考虑,一下,未来,的,扩展性,比如,表,设计,的,时候,留,一些,扩展,字段,接口,设计,的,时候,考虑,一下,未来,可能,的,需求,但是,不要,提前,做,复杂,的,优化,比如,分库,分表,读写,分离,等等,这些,要,等,真正,需要,的,时候,才,做。

而且,很多,时候,你,预测,的,未来,的,情况,可能,不会,发生,或者,和,你,预测,的,不一样,提前,做,了,优化,可能,白,做,了,所以,不如,等,真正,需要,的,时候,再,做,那样,更,有,针对性,也,更,高效。

九、稳定性比性能更重要

第九个,道理,稳定性,比,性能,更,重要,不要,为了,追求,性能,而,牺牲,稳定性。

刚,入行,的,时候,我,很,追求,性能,觉得,性能,越,高,越,好,为了,提高,一点,性能,愿意,做,很多,复杂,的,优化,但是,后来,才,发现,稳定性,比,性能,更,重要,一个,性能,稍微,差,一点,但是,稳定,的,系统,比,一个,性能,很,高,但是,经常,出,问题,的,系统,好,太多。

有,一次,我,为了,提高,查询,性能,把,事务,隔离,级别,从,可重复读,改成,了,读,已提交,这样,能,减少,锁,等待,提高,并发,性能,但是,改,了,之后,线上,出,了,数据,不一致,的,问题,因为,读,已提交,的,隔离,级别,下,会,有,不可重复读,的,问题,导致,一些,业务,逻辑,出,错,后来,赶紧,改,回,可重复读,才,解决,问题,但是,已经,造成,了,一些,数据,问题,花,了,很,久,才,修复。

那,时候,我,才,明白,稳定性,比,性能,更,重要,不要,为了,追求,一点,性能,提升,就,做,有,风险,的,改动,那样,可能,会,导致,系统,不,稳定,造成,更,大,的,损失。

性能,问题,一般,只是,慢,一点,用户,可能,还,能,忍受,但是,稳定性,问题,比如,系统,崩溃,数据,丢失,数据,不一致,等等,这些,是,用户,不能,忍受,的,会,造成,很,大,的,影响,和,损失,所以,稳定性,永远,是,第一位,的,性能,是,第二位,的。

而且,很多,性能,优化,都是,有,风险,的,比如,改,配置,改,SQL,加,索引,等等,都,可能,会,出,问题,所以,做,性能,优化,的,时候,一定,要,充分,测试,确保,没有,问题,再,上线,而且,要,有,回滚,方案,万一,出,了,问题,能,快速,回滚,减少,影响。

十、持续学习,保持敬畏

最后,一个,道理,持续,学习,保持,敬畏,MySQL,性能,调优,是,一门,很深,的,学问,永远,学,不完,要,保持,学习,的,心态,也要,对,数据库,保持,敬畏。

做,了,三年,MySQL,性能,调优,我,越,做,越,觉得,自己,懂,的,太少,MySQL,的,东西,太,多,了,源码,原理,索引,实现,事务,实现,锁,机制,优化器,等等,每,一个,都,很,深,要,花,很多,时间,去,学习,和,理解,而且,MySQL,也,在,不断,更新,新,版本,有,新,功能,新,特性,也要,不断,学习。

而且,线上,的,环境,很,复杂,各种,情况,都,可能,发生,很多,问题,是,你,从来,没,遇到,过,的,需要,不断,学习,不断,积累,经验,才能,应对,所以,一定,要,保持,学习,的,心态,不要,觉得,自己,懂,了,很多,就,骄傲,自满,那样,很,容易,出,问题。

同时,也,要,对,数据库,保持,敬畏,数据库,是,系统,的,核心,存储,着,最重要,的,数据,一旦,出,问题,影响,很,大,所以,操作,数据库,的,时候,一定,要,小心,谨慎,不要,随便,在,生产,环境,执行,危险,的,操作,比如,drop table,delete,without where,等等,执行,之前,一定,要,确认,清楚,最好,先,在,测试,环境,验证,而且,要,备份,数据,万一,出,了,问题,能,恢复。

而且,做,性能,调优,的,时候,也,要,谨慎,不要,随便,改,配置,改,SQL,加,索引,要,先,分析,清楚,再,改,而且,要,充分,测试,确保,没有,问题,再,上线,不要,因为,自己的,疏忽,导致,线上,出,问题。

十一、写在最后

做,了,三年,MySQL,性能,调优,踩,了,很多,坑,也,学,到,了,很多,道理,今天,分享,出来,希望,能,给,正在,做,数据库,优化,的,朋友,一些,参考,和,启发。

MySQL,性能,调优,是,一门,很深,的,学问,需要,不断,学习,不断,实践,不断,总结,才能,越,做,越,好,而且,很多,道理,是,要,自己,踩,了,坑,之后,才能,真正,明白,的,所以,不要,怕,踩坑,踩,坑,也是,成长,的,过程。

最后,希望,大家,都,能,做好,MySQL,性能,调优,让,自己的,系统,又,快,又,稳定,也,希望,大家,都,能,在,工作,中,不断,学习,不断,成长,成为,更,优秀,的,工程师。

也,欢迎,大家,在,评论,区,分享,你们,做,MySQL,性能,调优,的,经验,和,踩,过,的,坑,一起,交流,一起,进步。