这个问题面试官要么不问,一问的话,可以通过如下引导的话术,从单机版sql调优,sql性能监控,缓存和分库分表以及压力测试方面全面展示自己数据库方面的调优技能。
1 首先说,我们项目会用zabbix(或cat)等组件监控sql数据库,一旦根据配置,一旦有执行时间超过5秒(或10秒,反正自己说),我们就会收到告警邮件。
这里其实很多初级程序员是无法接触到监控组件的,这些组件的安装和配置基本上是由运维做,甚至有些小项目是不用此类监控组件,但不影响在面试时说。而且这块不难,基本上看下zabbix和cat的相关配置后就能说。
为什么要先说这点?第一,很多初级开发不知道,你说了就能展示系统监控技能。第二很多初级开发在面试时直接说优化,但优化的前提是要发现待优化的点,一旦说了监控组件,那么就能更好地展示发现问题、分析问题和解决问题方面的技能。
2 说下通过执行计划(即explain)分析慢查询的过程,这比单纯说优化技巧要高级得多,因为这块能展示分析问题解决问题的技能。
这块可以说,遇到从zabbix发过来的慢查询语句,我们会看下日志,看这句sql是哪个业务模块发的,同时用执行计划分析下。这里mysql,oracle和sql server等数据库都有执行计划,面试时甚至都不要说如何打开执行计划并分析,只要说下执行计划包含哪些要素,以及从中该如何分析。
执行计划一般是包含这句sql语句里各动作的耗时因素,比如是全表扫描耗时,还是连接时耗时,或者是group by分组时耗时。这块大家可以具体看下执行计划长什么样。
在真实项目里,单句sql语句一般可供优化的操作不多,一般是通过执行计划看到有全表扫描的情况,所以建个索引,如果发现有回表的情况,所以建个复合索引,如果发现一个长语句里有重复的子sql模块,那么可以用with语句重构。此外,本人有专门的文章讲单机版sql调优的技巧。
但是这些措施毕竟属于单机版的,说得再好再全面也只是属于单机版的调优措施,而单机版的优化措施仅仅属于初级开发层面。
3 但是,本人看到有些网上列的措施,真实项目里基本不用,或者是很慎重,如果大家面试时说了如下的优化措施,面试官真可能会细问,一旦没说好,那还不如不说。
比如是更新事务隔离级别的策略,或者是事务(包含分布式事务)回滚或提交的策略,变更mysql引擎或配置文件,或者是关闭写日志的动作。凡是遇到此类更新全局性配置或数据库动作的操作,大家一定要慎重。
这些操作真可能是优化性能,但这些全局性的配置更新后会引发什么问题,或者是会潜在引入哪些风险,谁也不知道,所以项目经理一般不会冒着风险引入此类优化措施。
4 以上说的都是单机版的优化策略,说好以后大家可以继续从集群、缓存和分库分表等分布式组件层面,说下sql调优的措施。先说集群方面。
这里大家可以说项目里引入mysql主从集群,大多数项目用的是一主一从,由此实现读写分离。这里对于初级开发的话,可以适当看下配置mysql主从的命令,而且大多数项目会用到主从,所以这块不讲白不讲。不过集群的话,一主一从就够了,不必讲一主多从。
这里顺带提一句,本人在面试中听到有人说用docker配置管理mysql主从集群,这里千万注意,由于docker容器会不定期down机,所以把包含大量数据的mysql放docker里是不安全的,基本上没项目组敢这样用。
5 再说下缓存,这里固然可以说spring缓存,也可以说mybatis缓存,但更可以说redis缓存。
这里可以说,我们业务里,会把热门数据放入redis从而提升效率,放入redis缓存后,能减轻因频繁访问数据库导致的压力。但在讲redis时,别说做持久化,因为持久化是把缓存数据放文件,但缓存的数据一般都是热门数据,而且在数据库里有都,所以没必要。
在说redis缓存时,可以说解决过的问题,比如缓存穿透和超时时间,缓存穿透是指大批量访问了数据库里不存在的数据,这样该数据没机会放入缓存,所以每次请求都走缓存但还是依然走数据库,解决缓存穿透的方法是缓存空数据或不存在数据库的数据。redis超时时间是指,如果放入redis的数据不设置超时时间,该数据会一直存在内存,从而导致内存OOM,解决方法是设置个超时时间。
关于redis的细节,大家可以看我如下的文章,其中也包含了面试相关说辞。
而且在说redis时,尽量说用的是redis集群,比如主从集群或cluster集群,但别说哨兵,哨兵集群目前不怎么用。很多项目为了提升redis可用性,或者是分摊缓存的压力,都会用集群。对初级开发来说,就可以提一句,我们项目用的是主从redis集群,至于如何搭建,以及出了故障如何转移数据,这些是面向架构师的问题。
6 如果有条件,可以说用了分库分表组件,比如mycat。
说mycat分库组件时,需要注意如下要点,第一该表数据规模很大,至少百万级,如果十万级都没必要用。第二通过schema.xml, rule.xml, server.xml设置分库方式,这块可以看下。第三说下用mycat后要改写针对全表扫描的操作,如果真有,用n+1模式,即n个分库表外带1个主表。
分库组件说起来不容易,对初级开发来说,可以说项目里用到mycat,同时看下配置文件和api,说到这个程度即可,如果有能力的话,可以再说下全局表和子表之间数据清洗等操作。
7 用压力测试把所有的点串起来讲,压力测试可以是用jmeter发高并发的请求。
这块可以说,我们系统上线前,是预估有每秒500到1000个并发量,所以上线前,我们在测试环境上搭建个和生产环境上一样的系统,其中包含了redis和mycat。在这种情况下,我们用jmeter发请求,通过设置1秒发500个请求,同时各服务器接zabbix等监控组件。
在压力测试的情况下,我们通过zabbix收到不少告警信息,对此我们用执行计划分析,针对性地建了索引,并且改进了不少sql语句,比如引入with语句。在全面引入单机版调优措施后,我们发现数据库的压力依然很大,表现形式是zabbix依然会报出慢查询,这种情况下我们引入了redis缓存,你想说的话再可以说引入了mycat分库组件。
在引入redis和mycat后,我们加大了每秒的并发量,比如用jmeter一秒发了1000个请求,此时会发现redis缓存穿透,同时发现OOM增大,此时通过排除,我们解决了因redis缓存穿透和超时时间而导致的问题。
这里既然提到了压力测试,那么可以顺带说下通过压力测试发现并解决了内存OOM问题,反正不说白不说,相关说辞大家可以参考我如下的问题。
大家可以看下,上述提到的说辞不难,哪怕是初级开发经过少量时间地点准备后也能说,但事实上不少初级开发技能上只限于做增删改查的业务,调优方面只限于单机版调优措施,或者甚至可能从网上看到些真实项目里不大可能操作的优化措施。
但是如果大家用上文给出的步骤,在面试官问及sql优化时,一步步引导面试官提问,将会是个什么场景?
1 为了发现慢查询的问题,在我们项目里是用zabbix监控数据库,凡是通过这个组件发现的慢查询语句,我们会用执行计划来分析。当然这里需要准备下zabbix配置细节和执行计划的细节,一旦面试官问及能展开说明,同时把话题引到执行计划以及后继的优化措施方面。
2 然后可以说下执行计划长什么样,以及你用过的单机版调优措施,但一定别太拘泥于单机版说辞,说好以后再提一句,我们项目还用mysql集群、缓存和分库组件来优化数据库性能。
3 这里可以展开说mysql主从集群,redis和mycat组件怎么配置怎么用,更可以说解决过redis因缓存穿透和超时时间导致的问题。说到这里也别停,再说一句,我们项目里是通过压力测试发现和解决数据库性能问题。
4 既然把话题引到了压力测试,就继续说压力测试的实施细节,之前没机会提到的各种优化措施这里可以全面展开说。但请注意,压力测试方面,一定要突出通过jmeter发高并发请求,用zabbix发现问题以及分析解决问题的思路。同时可以利用压力测试说说还解决过内存性能问题。
说到这里的话,大家可以想象下,哪怕你之前只用过索引调优,只是在理论层面看熟执行计划或redis等细节,但经过准备后有条理地层层说出上述说辞,那一定能全面展示监控发现数据库问题,分析解决数据问题,通过分布式组件调优sql性能等技能。
在面试过程中,用上述说辞去挑战高级开发的职位也不逊色,很多有5年开发经验的求职者如果不经过准备甚至还未必能达到这一效果,甚至如果再去完善下redis和mycat等细节,按上述思路和说辞去挑战架构师的职位也不会落入下风。
当然,既然你已经准备好上述数据库调优的说辞后,如果没机会说那么太可惜了。在面试官不主动提及的前提下,大家可以通过如下方式不露痕迹地让面试官提问,从而引出事先准备好的说辞。
1 自我介绍或介绍项目时,主动提及,本人在项目里不仅有数据库的使用经验, 而且还有数据库调优的实践技能,面试官一旦问及,主动按条理展开。
2 如果面试官不问,在回答好任何数据库相关问题后,顺带多说一句。比如被问及,你们项目用什么数据库,用什么orm组件连数据库,在回答好本职问题后再说一句,在项目里,我不仅熟悉各种数据库的操作,还有调优sql的经验。然后坐等面试官提问,再展开。
3 在被问及任何分布式组件问题时可以展开,事实上大多数面试一般都会问redis,所以可以在回答好相关问题后展开说,我在项目里用过redis来解决过数据库性能问题,在数据库性能调优方面,我能否从头说起?然后等面试官正面回复后,按条理展开。
4 在被问及任何测试相关问题后,可以通过引导展开。比如被问及你们单元测试是怎么做的?在回答好本职问题后可以顺带说一句,我在项目里还通过压力测试来调优sql性能,然后展开。
5 如果感觉在面试中实在没机会说,可以用这个方式来兜底。面试过程中,当面试官问好问题后,一定会问,我问题问好了,你有什么问题要问我。此时你可以直接说,我在项目里还有sql调优经验,刚才没机会说,现在能否说下?然后再展开。
不过切记,上述说辞涵盖面比较广,比如以前文科考试做问答题,有5个点,每个点满分3分。在准备上述sql调优说辞以及面试实践时,一定得先涵盖每个点,比如每个点先提到,争取每个点先拿个2分,再细化说每个点。但千万别只说一个点,比如只说单机版调优,这样你说到天上,顶多只能拿满这个点的分数,其它点就被忽视了,这样太亏了。
写在最后,本人忍不住想说,面试一定是要优先证明自己的真实项目经验,在这基础上面试官才会问技术。比如通过自学入行或培训班入行的同学,如果不优先去证明自己真实项目经验,哪怕准备了再说的技术说辞和本文提到的值钱说辞也没用。至于项目经验怎么准备怎么说,大家可以看我如下的文章。
如果大家感觉本文有帮助,那么就请以举手之劳帮忙点下赞。
顺带发起个咨询。如果大家想进一步了解简历和面试方面的技能,可以咨询我。
1 用资料帮大家巩固spring boot,甚至是spring boot整合 分布式组件 和微服务的技能,同时提供Java面试方面的资料。这些资料在市面上有明码标价,这些资料的钱就超过咨询的费用了。 但本人不负责技术提升,人家培训班收费上万的事情本人做不了。
2 提供简历辅导服务,经本人辅导后的简历,基本上都能大大提升竞争力,从而得到面试机会。
3 以电话交流的方式提供面试辅导服务,包括但不限于教如何介绍商业项目经验,如何在面试中证明spring boot能力,如何在项目中证明调优看日志和分布式组件等方面的亮点。尤其地,在辅导过程中本人还会教授“引导方法”,告诉大家如何在准备的基础上,引导面试官问出你的亮点和技能。
4 甚至还能提供就业辅导和薪资方面的咨询。如果条件合适,还有外企能公司的内推机会。