MySQL分区表专题

1.对表进行分区的原因和场景

改善大表、具有各种访问模式的表的可伸缩性、可管理性,提高效率
优点:
与单个磁盘或文件系统分区相比,可存储更多的数据,2T→16T;
通过删除与增加有关数据的分区,很容易删除或增加那些数据;
一些查询能得到优化;
通过跨多个磁盘甚至服务器分散查询,获得更大的查询吞吐量;
MySQL5.5之后支持所有函数的分区优化,之前只有两个聚合函数可以使用在分区表中。

2.分区类型

基本分区类型:
RANGE分区:基于属于一个给定连续区间的列值,把多行分配给分区
LIST分区:类似于按RANGE分区,区别是LIST分区是基于列值匹配一个离散值集合中的某个值来进行选择
HASH分区:基于用户定义的表达式的返回值来进行选择分区,该表达式使用将要插入到表中的这些行的列值进行计算,这个函数可以包含MySQL中有效的、产生非负整数值的任何表达式
KEY分区:类似于HASH分区,区别在于KEY分区只支持计算一列或多列

3.RANGE分区

改成分区表:

alter table titles
partition by range (year(from_date))  #基于from_date列中的年份来分区
(
partition p01 values less than (1985),
partition p02 values less than (1986),
partition p03 values less than (1987),
partition p04 values less than (1988),
partition p15 values less than (1999),
partition p16 values less than (MAXVALUE)
);

直接创建分区表:

create table t1 (id int ,name varchar(20), age int)
partition by range(age)
(
partition p01 values less than (10), #不包括10,即<10
partition p02 values less than (20), #不包括20,即≥10且<20
partition p03 values less than (30),
partition p04 values less than (maxvalue)
);

注:分区的名称是不区分大小写的


分区文件

分区表的文件也有所不同,frm和普通表一样是表结构信息
.par文件是分区信息
.ibd是每个分区的数据信息,有多个

4.LIST分区

create table t2 (id int, cid int ,name varchar(20),pos_date datetime)
partition by list (cid)
(
partition p01 values in (1,3,5),
partition p02 values in (2,8,9),
partition p03 values in (4,6,7)
);

5.HASH分区

具体算法较为复杂,要看官方文档或源码
但是使用起来很方便:

create table t3(id int,cid int,name varchar(20),pos_date datetime)
parttion by hash(cid) 
partitions 4;

另有LINEAR HASH分区
优点在于增加、删除、合并和拆分分区将变得更加快捷,有利于处理含有极大量(1T)数据的表
缺点在于数据分布可能不够均匀,容易产生hotspot nodes
语法和普通哈希分区区别不大,例:

create table t3(id int,cid int,name varchar(20),pos_date datetime)
parttion by linear hash(cid) 
partitions 4;

6.KEY分区

使用几率不大

create table t4(id int,cid int,name varchar(20),pos_date datetime)
parttion by linear key(cid) 
partitions 4;

7.多列分区

在5.5之后可以依据多个字段进行分区

create table t5 (a int , b int , c int)
partition by range columns(a,b)
(
partition p01 values less than (10,10),
partition p02 values less than (10,20), #前一个是a列,后一个是b列
partition p03 values less than (10,30),
partition p04 values less than (10,maxvalue),
partition p05 values less than (maxvalue,maxvalue)
);

8.子分区

子分区是分区表中每个分区的再次分割,
子分区可以用于特别大的表,在多个磁盘间分配数据和索引

create table t6(id INT, udate DATE)
partition by range (YEAR(udate))
subpartition by HASH(TO_DAYS(udate))
subpartitions 2
(
partition p0 VALUES LESS THAN (1990),
partition p1 VALUES LESS THAN (2000),
partition p2 VALUES LESS THAN (maxvalue)
);
子分区文件

将子分区保存在不同的存储上,优化I/O性能
是互联网公司非常常见的操作

create tabl ts (id int ,udate DATE)
partition by range(YEAR(udate))
subpartition by HASH(TO_DAYS(udate))
(
partition p0 values less than (1990)
(
subpartition s0
DATA DIRECTORY = '/disk0/data'
INDEX DIRECTORY = 'disk0/idx',
subpartition s1
DATA DIRECTORY = '/disk1/data'
INDEX DIRECTORY = 'disk1/idx'
),
partition p1 values less than (2000)
(
subpartition s2
DATA DIRECTORY = '/disk2/data'
INDEX DIRECTORY = 'disk2/idx',
subpartition s3
DATA DIRECTORY = '/disk3/data'
INDEX DIRECTORY = 'disk3/idx'
)
);

记得不同目录都要给OS层mysql用户授权


子分区文件

此时能看到有isl文件,是个文本文件,打开后是一个路径,保存了ibd文件的位置
我们也可以修改这个isl文件来修改目录位置;
提醒:
每个分区必须有相同数量的子分区;
假设一个分区定义了子分区,那么其他分区也必须定义子分区;
子分区名称不能重复;

9.分区管理

9.1简单修改分区
使用alter语句,效果和先删除原表再按新的分区方式重新建表效果相同
也可以用在改变分区的类型

alter table t3 partition by key(id) partitions 2;

空表修改就已经几百毫秒了,
生产环境是不要贸然进行操作

9.2删除指定RANGE&LIST分区
查看某数据位于哪个分区:

EXPLAIN PARTITIONS SELECT * FROM table_name WHERE my_column = N;

查看某表分区情况及分区数据量:

select table_name,partition_name,table_rows
from information_schema.PARTITIONS
where TABLE_NAME = 'api_log';

删除分区:

alter table t1 drop partition p02;

删除分区数据:

alter table t1 truncate partition p01;

9.3增加RANGE&LIST分区
使用alter table ... add partition语句,
但是对于RANGE分区的表,只能add partition增加新分区到分区列表的高端,不能加到低端
对于LIST分区,不能包含现有分区值列表中的任意值
例:

alter table history_new add partition (partition p202302 values less than (1677600000));

9.4分区重组
使用reorganize可对现有分区重分成多个分区,也可以将多个现有分区合并成一个分区
新分区不能有任何重叠区间(RANGE)或值几何(LIST),还必须覆盖原有区间,
另外合并RANGE分区,只能重新组织相邻分区,不能合并隔着的RANGE分区

alter table t1 reorganize partition p01 into(
  partition s0 values less than (5),
  partition s1 values less than (10));
alter table t1 reorganize partition s0,s1 into(
  partition p01 values less than (10));

一般用于热点分区再拆分

9.5管理HASH&KEY分区数量
使用alter...coalesce partition缩减分区数量
使用alter...add partition增加分区数量

alter table t2 coalesce partition 2;
alter table t2 add partition partitions 6;

注:语句中的数量指的是加减的数量,不是目标数量

9.6分区维护
重建分区:
对于分区表,不支持check table,optimize table, analyze table,repair table(innodb引擎本来也不能用,这些命令都是针对myisam引擎的)
可以使用alter table许多扩展来再一个或多个分区上直接执行这些操作
例如先把数据存在临时文件中,删除分区中记录再重新插入他们,具有同样效果,可用于整理分区碎片(过程有大量IO,不要经常操作)

alter table t1 rebuild partition p01,p02;

优化分区:
如果分区中删除大量的行,或对一个有可变长度的行做了许多修改,可以回收没有使用的空间并整理分区数据文件的碎片(过程相对rebuild性能要稍微好一些,但也还是消耗很高)

alter table t1 optimize partition p01,p02;

检查与修复分区:
用于分区文件损坏等情况,比如意外停机

alter table t1 check partition p01,p02;
alter table t1 repair partition p01,p02;

10.分区索引

mysql分区后每个分区成了独立的文件,虽然从逻辑上还是一张表其实已经分成了多张独立的表,从“information_schema.INNODB_SYS_TABLES”系统表可以看到每个分区都存在独立的TABLE_ID,由于Innodb数据和索引都是保存在".ibd"文件当中(从INNODB_SYS_INDEXES系统表中也可以得到每个索引都是对应各自的分区(primary key和unique也不例外)),所以分区表的索引也是随着各个分区单独存储。

在INNODB_SYS_INDEXES系统表中type代表索引的类型;0:一般的索引,1:(GEN_CLUST_INDEX)不存在主键索引的表,会自动生成一个6个字节的标示值,2:unique索引,3:primary索引;所以当我们在分区表中创建索引时其实也是在每个分区中创建索引,每个分区维护各自的索引(其实也就是local index);对于一般的索引(非主键或者唯一)没什么问题由于索引树中只保留了索引key和主键key(如果存在主键则是主键的key否则就是系统自动生成的6个的key)不受分区的影响;但是如果表中存在主键就不一样了,虽然在每个分区文件中都存在主键索引但是主键索引需要保证全局的唯一性就是所有分区中的主键的值都必须唯一(唯一键也是一样的道理),所以在创建分区时如果表中存在主键或者唯一键那么分区列必须包含主键或者唯一键的部分或者全部列(全部列还好理解,部分列也可以个人猜测是为了各个分区和主键建立关系),由于需要保证全局性又要保证插入数据更新数据到具体的分区所以就需要将分区和主键建立关系,由于通过一般的索引进行查找其它非索引字段需要通过主键如果主键不能保证全局唯一性的话那么就需要去每个分区查找了,这样性能可想而知。

按性能依次降低的顺序,排序如下:
1.主键分区
主键分区即字段是主键同时也是分区字段,性能最好

  1. 部分主键+分区索引
    使用组合主键里面的部分字段作为分区字段,同时将分区字段建索引
    3.分区索引
    没有主键,只有分区字段且分区字段建索引
    4.分区+分区字段没有索引
    只建了分区,但是分区字段没有建索引
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容