文章目录

  • 1 分区表概念
  • 2 分区表应用场景
  • 3 分区表局限性
  • 4 分区表原理
  • 5 分区表类型
  • 6 分区表使用
  • 7 在使用分区表的时候需要注意的问题



1 分区表概念

  分区表即按照一定规则将一个表的数据存储在多个表中,并且在物理内存中使用独立的数据文件。

2 分区表应用场景

  分区表有以下应用场景:

  • 表非常大以至于无法将全部数据放在内存中,或者只在表的最后部分有热点数据,其他均是历史数据。
  • 分区表的数据更容易维护,比如批量删除大量数据可以使用清除整个分区的方式。另外,分区表使得对一个独立分区进行优化、检查、修复等操作更加容易。
  • 分区表的数据可以分布在不同的物理设备上,从而高效地利用多个硬件设备。
  • 可以使用分区表来避免某些特殊的瓶颈,比如innodb的单个索引的互斥访问和ext3文件系统的inode锁竞争等。
  • 可以备份和恢复独立的分区,有时候备份数据或者恢复数据可能并不需要针对全量数据,使用分区表可以减少I/O消耗。

3 分区表局限性

  分区表也存在一些局限性:

  • 一个表最多只能有1024个分区,在5.7版本的时候可以支持8196个分区。
  • 在早期的mysql中,分区表达式必须是整数或者是返回整数的表达式,在mysql5.5中,某些场景可以直接使用列来进行分区。
  • 如果分区字段中有主键或者唯一索引的列,那么所有主键列和唯一索引列都必须包含进来。
  • 分区表无法使用外键约束。

4 分区表原理

  分区表由多个相关的底层表实现,这个底层表也是由句柄对象标识,我们可以直接访问各个分区。存储引擎管理分区的各个底层表和管理普通表一样(所有的底层表都必须使用相同的存储引擎),分区表的索引知识在各个底层表上各自加上一个完全相同的索引。从存储引擎的角度来看,底层表和普通表没有任何不同,存储引擎也无须知道这是一个普通表还是一个分区表的一部分。

5 分区表类型

  • 范围分区:根据列值在给定范围内将行分配给分区。
  • 列表分区:类似于按range分区,区别在于list分区是基于列值匹配一个离散值集合中的某个值来进行选择。
  • 列分区:mysql从5.5开始支持column分区,可以认为是range和list的升级版,在5.5之后,可以使用column分区替代range和list,但是column分区只接受普通列不接受表达式。(实际上没什么卵用)
  • Hash分区:基于用户定义的表达式的返回值来进行选择的分区,该表达式使用将要插入到表中的这些行的列值进行计算。这个函数可以包含myql中有效的、产生非负整数值的任何表达式。
  • Key分区:基于用户定义的表达式的返回值来进行选择的分区,该表达式使用将要插入到表中的这些行的列值进行计算。这个函数可以包含myql中有效的、产生非负整数值的任何表达式。(更加没卵用)
  • 子分区:在分区的基础之上,再进行分区后存储。

6 分区表使用

  试想如果需要从非常大的表中查询出某一段时间的记录,而这张表中包含很多年的历史数据,数据是按照时间排序的,此时应该如何查询数据呢?因为数据量巨大,肯定不能在每次查询的时候都扫描全表。考虑到索引在空间和维护上的消耗,也不希望使用索引,即使使用索引,也会产生大量的碎片,还会产生大量的随机IO,而且当数据量超大的时候,索引也就无法起作用了,此时就可以考虑使用分区来解决。
  分区表的使用有两种方式:

  1. 全量扫描数据,不要任何索引。使用简单的分区方式存放表,不要任何索引,根据分区规则大致定位需要的数据为止,通过使用where条件将需要的数据限制在少数分区中,这种策略适用于以正常的方式访问大量数据。
  2. 索引数据,并分离热点。如果数据有明显的热点,而且除了这部分数据,其他数据很少被访问到,那么可以将这部分热点数据单独放在一个分区中,让这个分区的数据能够有机会都缓存在内存中,这样查询就可以只访问一个很小的分区表,能够使用索引,也能够有效的使用缓存。

7 在使用分区表的时候需要注意的问题

  • null值会使分区过滤无效。
  • 分区列和索引列不匹配,会导致查询无法进行分区过滤。
  • 选择分区的成本可能很高。
  • 打开并锁住所有底层表的成本可能很高。
  • 维护分区的成本可能很高。