最全为什么阿里不推荐使用MySQL分区表?,java中级面试题库weixin

难道这样就够了吗?不,远远不够!

提前多熟悉阿里往年的面试题肯定是对面试有很大的帮助的,但是作为技术性职业,手里有实打实的技术才是你面对面试官最有用的利器,这是从内在散发出来的自信。

备战阿里时我花的最多的时间就是在学习技术上,占了我所有学习计划中的百分之70,这是一些我学习期间觉得还是很不错的一些学习笔记

我为什么要写这篇文章呢,其实我觉得学习是不能停下脚步的,在网络上和大家一起分享,一起讨论,不单单可以遇到更多一样的人,还可以扩大自己的眼界,学习到更多的技术,我还会在csdn、博客、掘金等网站上分享技术,这也是一种学习的方法。

今天就分享到这里了,谢谢大家的关注,以后会分享更多的干货给大家!

阿里一面就落马,恶补完这份“阿里面试宝典”后,上岸蚂蚁金服

阿里一面就落马,恶补完这份“阿里面试宝典”后,上岸蚂蚁金服

image.png

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

  • 用MyISAM表锁验证

| session_1 | session_2 |

| :-- | — |

| alter table t engine=myisam;

update tt set c=sleep(100)

where ftime=‘2017-4-1’; | |

| | select * from tt where ftime=‘2018-4-1’;

(Query OK)

select * from tt where ftime=‘2017-5-1’;

(阻塞) |

在session1,sleep(100)将该语句的执行时间设为100s。由于MyISAM引擎只支持表锁,所以这条update语句会锁住整个表tt上的读。

但session2的第一条查询语句可以正常执行,第二条语句才进入锁等待。

因为MyISAM的表锁实现在引擎层,session1加的表锁,其实是锁在分区p_2018。因此,只会堵住在这个分区上执行的查询,其他分区查询不受影响。

分区表使用起来看来挺好使的呀,为啥禁用?

使用分区表的一个重要原因就是单表过大。那若不使用分区表,就要手动分表。

手动分表 V.S 分区表

===========================================================================

比如,按年份划分,分别创建普通表t_2017t_2018t_2019等。手工分表也要找到需要更新的所有分表,然后依次执行更新。

性能上和分区表没有差别。

  • 分区表由server层决定使用哪个分区

  • 手动分表由应用层代码决定使用哪个分表

所以从引擎层看,也没啥区别。

两种方式的区别,主要在server层。server层的分区表一个严重问题就是打开表的行为。

分区策略

===================================================================

第一次访问一个分区表时,MySQL需要把所有分区都访问一遍。

一个典型的报错场景:若一个分区表的分区很多,比如超过1000,而MySQL启动时,open_files_limit参数默认值1024,则在访问该表时,由于需要打开所有文件,导致打开表文件的个数超过了上限而报错。

比如对一个包含很多分区的表,执行insert直接报错:

这条insert其实只需要访问一个分区,但语句报错了。这个表是MyISAM,如果使用InnoDB,不会出现该问题。

MyISAM分区表使用通用分区策略(generic partitioning),每次访问分区都由server层控制。通用分区策略,是MySQL一开始支持分区表的时候就存在的代码,在文件管理、表管理的实现上很粗糙,性能问题很严重。

MySQL 5.7.9开始,InnoDB引入本地分区策略(native partitioning),在InnoDB内部自己管理打开分区的行为。

MySQL 5.7.17开始,将MyISAM分区表标记为deprecated。

MySQL 8.0开始,已经禁止创建MyISAM分区表,只允许创建已经实现了本地分区策略的引擎。

目前只有InnoDB和NDB引擎支持本地分区策略。

分区表的server层行为

============================================================================

对于server层,一个分区表就只是一个表。

如图,分别是该例的操作序列和执行结果图。

  • 分区表的MDL锁

| session_1 | session_2 |

| :-- | — |

| begin;

select * from tt

where ftime=‘2018-4-1’; | |

| | alter table tt truncate partition p_2017

(阻塞) |

  • show processlist

虽然session2只需操作p_2107分区,但因为session1持有整个表tt的MDL锁,导致session2的alter语句被阻塞。

所以分区表在做DDL时,影响会更大。若使用的普通分表,则当你在truncate一个分表时,肯定不会跟另外一个分表上的查询语句,出现MDL锁冲突。

小结

在server层,认为这是同一张表,因此所有分区共用同一MDL锁

在引擎层,认为这是不同表,因此MDL锁之后的执行过程,会根据分区表规则,只访问必要的分区。

什么是必要的分区

根据SQL语句中的where条件,结合分区规则。比如上面的where ftime=‘2018-4-1’,根据分区规则year函数算出来的值是2018,那么就会落在p_2019分区。

但若这个where 条件改成 where ftime>='2018-4-1',虽然查询结果相同,但这时根据where条件,就要访问p_2019p_others俩分区。

若查询语句的where条件没有分区key,就只能访问所有分区了。当然,这并非分区表的问题。即使是使用业务分表,where条件中没有使用分表的key,也必须访问所有的分表。

分区表的应用场景

=======================================================================

一大优势是对业务透明,相对于用户分表来说,使用分区表的业务代码更简洁。还有,分区表可以很方便的清理历史数据。

如果一项业务跑的时间足够长,往往就会有根据时间删除历史数据的需求。这时按时间分区的分区表,就可直接通过alter table t drop partition …这个语法删掉分区,从而删掉过期的历史数据。

alter table t drop partition …是直接删除分区文件,跟drop普通表类似。与delete相比,优势是速度快、对系统影响小。

需要注意的是,我是以范围分区(range)为例和你介绍的。实际上,MySQL还支持hash分区、list分区等分区方法。

实际使用时,分区表跟用户分表,有两个问题:

  • 第一次访问时,需要访问所有分区

读者福利

由于篇幅过长,就不展示所有面试题了,感兴趣的小伙伴

35K成功入职:蚂蚁金服面试Java后端经历!「含面试题+答案」

35K成功入职:蚂蚁金服面试Java后端经历!「含面试题+答案」

35K成功入职:蚂蚁金服面试Java后端经历!「含面试题+答案」

更多笔记分享

35K成功入职:蚂蚁金服面试Java后端经历!「含面试题+答案」

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

.(img-S3PQXqjS-1715592652052)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值