mysql分区表的原理及优缺点 - SEO - 新闻资讯 - 爱可生
新闻资讯

mysql分区表的原理及优缺点

发布时间:2020-12-02 浏览次数:80

1.mysql分区表的原理

mysql分区表是由多个相关底层表实现的,它们也是通过句柄对象来表示,因此我们也可以直接访问各个分区,存储引擎管理分区的每个底层表就像管理普通表一样(所有底层表都必须使用相同的存储引擎),分区表的索引只需要在每个底层表上分别添加同一个索引,从存储引擎的角度来看,底层表与普通表并无什么不同,而存储引擎并不需要知道这是普通表还是属于一个分区表。

在分区表上的操作按照下面的操作逻辑进行:

select查询:

查询分区表时,分区表层首先打开并锁定所有底层表,优化器判断是否可以过滤一些分区,然后调用相应的存储引擎接口访问每个分区的数据。

insert操作:

写入记录时,分区层打开并锁定所有基础表,然后确定哪个分区接受该记录,然后将该记录写入相应的基础表。

delete操作:

在删除记录时,分区层首先打开并锁定所有的底层表,然后确定数据对应的分区,最后对相应的底层表执行删除操作。

update操作:

在更新数据条时,分区层首先打开并锁定所有底层表,然后 mysql确定需要更新的记录所在的分区,然后取出数据并更新,然后判断应该将更新后的数据放到哪个分区上,然后对底层表执行写操作,并对原始数据所在的底层表执行删除操作。

虽然每个操作都会打开并锁定所有底层表,但这并不意味着分区表在处理过程中会锁定整个表。如果存储引擎可以自己实现行级锁,比如innodb,那么相应的表锁将在分区级释放。这个锁定和解锁过程类似于普通Innodb上的查询。

2.在下面的场景中,分区可以起到非常大的作用:

A:表非常大以至于无法全部都放在内存中,或者只在表的最后部分有热点数据,其他都是历史数据

B:分区表的数据更容易维护,如:想批量删除大量数据可以使用清除整个分区的方式。另外,还可以对一个独立分区进行优化、检查、修复等操作

C:分区表的数据可以分布在不同的物理设备上,从而高效地利用多个硬件设备

D:可以使用分区表来避免某些特殊的瓶颈,如:innodb的单个索引的互斥访问,ext3文件系统的inode锁竞争等

E:如果需要,还可以备份和恢复独立的分区,这在非常大的数据集的场景下效果非常好

F:优化查询,在where字句中包含分区列时,可以只使用必要的分区来提高查询效率,同时在涉及sum()和count()这类聚合函数的查询时,可以在每个分区上面并行处理,最终只需要汇总所有分区得到的结果。

3.分区本身也有一些限制:

A:一个表最多只能有1024个分区(mysql5.6之后支持8192个分区)

B:在mysql5.1中分区表达式必须是整数,或者是返回整数的表达式,在5.5之后,某些场景可以直接使用字符串列和日期类型列来进行分区(使用varchar字符串类型列时,一般还是字符串的日期作为分区)。

C:如果分区字段中有主键或者唯一索引列,那么所有主键列和唯一索引列都必须包含进来,如果表中有主键或唯一索引,那么分区键必须是主键或唯一索引

D:分区表中无法使用外键约束

E:mysql数据库支持的分区类型为水平分区,并不支持垂直分区,因此,mysql数据库的分区中索引是局部分区索引,一个分区中既存放了数据又存放了索引,而全局分区是指的数据库放在各个分区中,但是所有的数据的索引放在另外一个对象中

F:目前mysql不支持空间类型和临时表类型进行分区。不支持全文索引

4.子分区的建立需要注意以下几个问题:

A:每个子分区的数量必须相同

B:只要在一个分区表的任何分区上使用subpartition来明确定义任何子分区,就必须在所有分区上定义子分区,不能漏掉一些分区不进行子分区。

C:每个subpartition子句必须包括子分区的一个名字

D:子分区的名字必须是唯一的,不能在一张表中出现重名的子分区

E:mysql数据库的分区总是把null当作比任何非null更小的值,这和数据库中处理null值的order by操作是一样的,升序排序时null总是在最前面,因此对于不同的分区类型,mysql数据库对于null的处理也各不相同。对于range分区,如果向分区列插入了null,则mysql数据库会将该值放入最左边的分区,注意,如果删除分区,分区下的所有内容都从磁盘中删掉了,null所在分区被删除,null值也就跟着被删除了。在list分区下要使用null,则必须显式地定义在分区的散列值中,否则插入null时会报错。hash和key分区对于null的处理方式和range,list分区不一样,任何分区函数都会将null返回为0.


上一篇: 没有了

下一篇: MySQL分布式数据库适用于飞机订票系统吗

相关推荐

产品试用 产品试用
400-820-6580 免费电话