MySQL性能优化分区之实战( 三 )


columns分区支持一个或者多个字段作为分区键,不支持表达式作为分区键,这点区别于range 和 list 分区 。需要注意的是range columns 分区键的比较是基于元组的比较,也就是基于字段组的比较,这和range分区有差异 。
create talbe rc3 ( a int, b int)partition by range columns(a, b) ( partition p01 values less than (0, 10), partition p02 values less than (10, 10), partition p03 values less than (10, 20), partition p04 values less than (10, 35), partition p05 values less than (10, maxvalue), partition p06 values less than (maxvalue, maxvalue),);insert into rc3(a, b) values(1, 10);select (1, 10) < (10, 10) from dual;-- 根据结果存放到p02分区上了select partition_name, partition_expression, partition_description, table_rowsfrom information_schema.partitionswhere table_schema = schema() and table_name = 'rc3'; ange columns分区键的比较(元组的比较)其实就是多列排序,先根据a字段排序再根据b字段排序,根据排序结果来分区存放数据,和range单字段的分区排序的规则实际上是一样的
六:hash分区Hash分区主要用来分散热点读,确保数据在预先确定个数的分区中可能的平均分布 。对一个表执行Hash分区时,mysql会对分区键应用一个散列函数,以此确定数据应当放在N个分区中的哪个分区 。
mysql支持两种hash分区,

  1. 常规hash分区和线性hash分区(linear hash分区),常规hash分区使用的是取模算法,对应一个表达式expr是可以计算出它被保存到哪个分区中,N = MOD(expr, num)
  2. 线性hash分区使用的是一个线性的2的幂运算法则 。
对指定的字段(整型字段)进行哈希,将记录平均的分配到分区中,使得所有分区的数据比较平均 。hash分区只需要指定要分区的字段和要分成几个分区,
expr是一个字段值或者基于某列值云散返回的一个整数,expr可以是mysql中有效的任何函数或者其它表达式,只要它们返回一个即非常熟也非随机数的整数 。
num 表示分区数量
-- HASHcreate table <table> ( // 字段) ENGINE=数据库引擎 DEFAULT CHARSET=utf8 AUTO_INCREMENT=1PARTITION BY HASH(expr)PARTITIONS <num>;常规hash分区方式看上去挺不错的,通过取模的方式来数据尽可能平均分布在每个分区,让每个分区管理的数据都减少,提高查询效率,可是当我们要增加分区时或者合并分区,问题就来了,假设原来是5个常规hash分区,现在需要增加一个常规分区,原来的取模算法是MOD(expr, 5), 根据余数0~4分布在5个分区中,现在新增一个分区后,取模算法变成MOD(expr, 6),根据余数0~6分区在6个分区中,原来5个分区的数据大部分都需要通过重新计算进行重新分区 。
常规hash分区在管理上带来了的代价太大,不适合需要灵活变动分区的需求 。为了降低分区管理上的代价,mysql提供了线性hash分区,分区函数是一个线性的2的幂的运算法则 。同样线性hash分区的记录被存在那个分区也是能被计算出来的 。线性hash分区的优点是在分区维护(增加、删除、合并、拆分分区)时,mysql能够处理的更加迅速,缺点是:对比常规hash分区,线性hash各个分区之间数据的分布不太均衡 。
-- LINEAR HASHcreate table <table> ( // 字段) ENGINE=数据库引擎 DEFAULT CHARSET=utf8 AUTO_INCREMENT=1PARTITION BY LINEAR HASH(expr)PARTITIONS <num>;七:key分区按照key进行分区非常类似于按照hash进行分区,只不过hash分区允许使用用户自定义的表达式,而key分区不允许使用用于自定义的表达式,需要使用mysql服务器提供的hash函数,同时hash分区只支持整数分区,而key分区支持使用出blob or text类型外的其他类型的列作为分区键 。
和hash功能一样,不同的是分区的字段可以是非int类型,如字符串、日期等类型 。
可以使用partition by key(expr)子句来创建一个key分区表,expr是零个或者多个字段名的列表 。key分区也支持线性分区linear key
partition by key(expr) partitions num;-- 不指定默认首选主键作为分区键,在没有主键的情况下会选择非空唯一键作为分区键partition by key() partitions num;-- linear keypartition by linear key(expr)create table <table> ( // 字段) ENGINE=数据库引擎 DEFAULT CHARSET=utf8 AUTO_INCREMENT=1PARTITION BY HASH(分区字段名)PARTITIONS <count>;八:子分区子分区(subpartition):是分区表中对每个分区的再次分割,又被称为复合分区,支持对range和list进行子分区,子分区即可以使用hash分区也可以使用key分区 。复合分区适用于保存非常大量的数据记录 。
-- 根据年进行分区
-- 再根据天数分区
-- 3个range分区(p0,p1,p2)又被进一步分成2个子分区,实际上整个分区被分成了 3 x 2 = 6个分区


推荐阅读