• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

关于java:面试官问我MySQL调优我真的是

java 搞代码 3年前 (2022-01-27) 39次浏览 已收录 0个评论

面试官要不你来讲讲你们对MySQL是怎么调优的?

候选者:哇,这命题很大阿…我认为,对于开发者而言,对MySQL的调优重点个别是在「开发标准」、「数据库索引」又或者说解决线上慢查问上。

候选者:而对于MySQL外部的参数调优,由业余的DBA来搞。

面试官:扯了这么多,你就是想表白你不会MySQL参数调优,对吧

候选者:草,被发现了。

面试官那你来聊聊你们平时开发的标准和索引这块,平时是怎么样的吧。

候选者:嗯,首先,咱们在生产环境下,创立数据库表,都是在工单零碎下实现的(那就天然须要DBA审批)。如果在创立表时检测到没有创立索引,那就会间接提醒warning(:

候选者:实践上来说,如果表有肯定的数据量,那就应该要创立对应的索引。从数据库查问数据须要留神的中央还是蛮多的,其中很多都是平时积攒来的。比如说:

候选者:1. 是否能应用「笼罩索引」,缩小「回表」所耗费的工夫。意味着,咱们在select 的时候,肯定要指明对应的列,而不是select *

候选者:2. 思考是否组建「联结索引」,如果组建「联结索引」,尽量将区分度最高的放在最右边,并且须要思考「最左匹配准则」

候选者:3.对索引进行函数操作或者表达式计算会导致索引生效

候选者:4.利用子查问优化超多分页场景。比方 limit offset , n 在MySQL是获取 offset + n的记录,再返回n条。而利用子查问则是查出n条,通过ID检索对应的记录进去,进步查问效率。

面试官:嗯…

候选者:5.通过explain命令来查看SQL的执行打算,看看本人写的SQL是否走了索引,走了什么索引。通过show profile 来查看SQL对系统资源的损耗状况(不过个别还是比拟少用到的)

候选者:6.在开启事务后,在事务内尽可能只操作数据库,并无意识地缩小锁的持有工夫(比方在事务内须要插入&&批改数据,那能够先插入后批改。因为批改是更新操作,会加行锁。如果先更新,那并发下可能会导致多个事务的申请期待行锁开释)

面试官:嗯,你提到了事务,之前也讲过了事务的隔离级别嘛,那你线上用的是什么隔离级别?

候选者:嗯,咱们这边用的是Read Commit(读已提交),MySQL默认用的是Repeatable read(可反复读)。选用什么隔离级别,次要看利用场景嘛,因为隔离级别越低,事务并发性能越高。

候选者:(个别互联网公司都抉择Read Commit作为次要的隔离级别)

候选者:像Repeatable read(可反复读)隔离级别,就有可能因为「间隙锁」导致的死锁问题。

候选者:但可能你曾经晓得,MySQL默认的隔离级别为Repeatable read。很大一部分起因是在最开始的时候,MySQL的binlog没有row模式,在read commit隔离级别下会存在「主从数据不统一」的问题

候选者:binlog记录了数据库表构造和表数据「变更」,比方update/delete/insert/truncate/create。在MySQL中,主从同步实际上就是利用了binlog来实现的(:

候选者:有了该历史起因,所以MySQL就将默认的隔离级别设置为Repeatable read

面试官:嗯,那我顺便想问下,你们遇到过相似的问题吗:即使走对了索引,线上查问还是慢。

候选者:嗯嗯,当然遇到过了

面试官那你们是怎么做的?

候选者:如果走对了索引,但查问还是慢,那一般来说就是表的数据量切实是太大了。

候选者:首先,思考能不能把「旧的数据」给”删掉”,对于咱们公司而言,咱们都会把数据同步到Hive,阐明曾经离线存储了一份了。

候选者:那如果「旧的数据」曾经没有查问的业务了,那最简略的方法必定是”删掉”局部数据咯。数据量升高了,那天然,检索速度就快了…

面试官:嗯,但个别不会删的

候选者:没错,只有极少局部业务能够删掉数据(:

候选者:随后,就思考另一种状况,能不能在查问之前,间接走一层缓存(Redis)。

候选者:而走缓存的话,又要看业务能不能忍耐读取的「非真正实时」的数据(毕竟Redis和MySQL的数据一致性须要保障),如果查问条件绝对简单且多变的话(波及各种group by 和sum),那走缓存也不是一种好的方法,保护起来就不不便了…

候选者:再看看是不是有「字符串」检索的场景导致查问低效,如果是的话,能够思考把表的数据导入至Elasticsearch类的搜索引擎,后续的线上查问就间接走Elasticsearch了。

候选者:MySQL->Elasticsearch须要有对应的同步程序(个别就是监听MySQL的binlog,解析binlog后导入到Elasticsearch)

候选者:如果还不是的话,那思考要不要依据查问条件的维度,做绝对应的聚合表,线上的申请就查问聚合表的数据,不走原表。

候选者:比方,用户下单后,有一份订单明细,而订单明细表的量级太大。但在产品侧(前台)透出的查问性能是以「天」维度来展现的,那就能够将每个用户的每天数据聚合起来,在聚合表就是一个用户一天只有一条汇总后的数据。

候选者:查问走聚合后的表,那速度必定杠杠的(聚合后的表数据量必定比原始表要少很多)

候选者:思路大抵的就是「以空间换工夫」,雷同的数据换别的中央也存储一份,进步查问效率

面试官那我还想问下,除了读之外,写性能同样有瓶颈,怎么办?

候选者:你说到这个,我就不困了。

候选者:如果在MySQL读写都有瓶颈,那首先看下目前MySQL的架构是怎么样的。

候选者:如果是单库的,那是不是能够思考降级至主从架构,实现读写拆散。

候选者:简略了解就是:主库接管写申请,从库接管读申请。从库的数据由主库发送的binlog进而更新,实现主从数据统一(在个别场景下,主从的数据是通过异步来保障最终一致性的)

面试官:嗯…

候选者:如果在主从架构下,读写仍存在瓶颈,那就要思考是否要分库分表了

候选者:至多在我前公司的架构下,业务是辨别的。流量有流量数据库,广告有广告的数据库,商品有商品的数据库。所以,我这里讲的分库分表的含意是:在原来的某个库的某个表进而拆分。

候选者:比方,当初我有一张业务订单表,这张订单表在广告库中,假设这张业务订单表曾经有1亿数据量了,当初我要分库分表

候选者:那就会将这张表的数据分至多个广告库以及多张表中(:

候选者:分库分表的最显著的益处就是把申请进行均摊(原本单个库单个表有一亿的数据,那假如我离开8个库,那每个库1200+W的数据量,每个库下分8张表,那每张表就150W的数据量)。

面试官你们是以什么来作为分库键的?

候选者:依照咱们这边的教训,一般来说是依照userId的(因为依照用户的维度查问比拟多),如果要依照其余的维度进行查问,那还是参照下面的的思路(以空间换工夫)。

面试官那分库分表后的ID是怎么生成的?

候选者:这就波及到分布式ID生成的形式了,思路有很多。有借助MySQL自增的,有借助Redis自增的,有基于「雪花算法」自增的。具体应用哪种形式,那就看公司的技术栈了,个别应用Redis和基于「雪花算法」实现用得比拟多。

候选者:至于为什么强调自增(还是跟索引是有序无关,后面曾经讲过了,你应该还记得)

面试官:嗯,那如果我要分库分表了,迁徙的过程是怎么样的呢

候选者:咱们个别采取「双写」的形式来进行迁徙,大抵步骤就是:

候选者:一、增量的音讯各自往新表和旧表写一份

候选者:二、将旧表的数据迁徙至新库

候选者:三、迟早新表的数据都会追得上旧表(在某个节点上数据是同步的)

候选者:四、校验新表和老表的数据是否失常(次要看能不能对得上)

候选者:五、开启双读(一部分流量走新表,一部分流量走老表),相当于灰度上线的过程

候选者:六、读流量全副切新表,进行老表的写入

候选者:七、提前准备回滚机制,长期切换失败能恢复正常业务以及有修数据的相干程序。

面试官:嗯…明天就到这吧

本文总结:

  • 数据库表存在肯定数据量,就须要有对应的索引
  • 发现慢查问时,查看是否走对索引,是否能用更好的索引进行优化查问速度,查看应用索引的姿态有没有问题
  • 当索引解决不了慢查问时,个别因为业务表的数据量太大导致,利用空间换工夫的思维
  • 当读写性能均遇到瓶颈时,先思考是否降级数据库架构即可解决问题,若不能则须要思考分库分表
  • 分库分表尽管能解决掉读写瓶颈,但同时会带来各种问题,须要提前调研解决方案和踩坑

线上不是给你炫技的中央,安稳才是硬道理。能用简略的形式去解决,不要用简单的形式

欢迎关注搞代码gaodaima网的微信公众号【Java3y】来聊聊Java面试,对线面试官系列继续更新中!

【对线面试官-挪动端】系列 一周两篇继续更新中!

【对线面试官-电脑端】系列 一周两篇继续更新中!

原创不易!!求三连!!


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:关于java:面试官问我MySQL调优我真的是

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址