mysql 分区PARTITIONS之分区方法

分区依据的字段必须是主键/唯一索引的组成部分,分区是为了快速定位数据,因此该字段的搜索频次较高应作为强检索字段,否则依照该字段分区毫无意义

mysql为我们提供的分区方法有下列几种
一、range、list
二、hash、key
三、columns

RANGE 分区:

按照数据大小范围分区(将数据使用某种条件,分散到不同的分区中)。如下,按文章的发布时间将数据按照2018年8月、9月、10月分区存放:

create table article_range(
    id int auto_increment,
    title varchar(64),
    content text,
    created_time int,   -- 发布时间到1970-1-1的毫秒数
    PRIMARY KEY (id,created_time)   -- 要求分区依据字段必须是主键的一部分
)charset=utf8
PARTITION BY RANGE(created_time)(
    PARTITION p201808 VALUES less than (1535731199),    -- select UNIX_TIMESTAMP('2018-8-31 23:59:59')
    PARTITION p201809 VALUES less than (1538323199),    -- 2018-9-30 23:59:59
    PARTITION p201810 VALUES less than (1541001599) -- 2018-10-31 23:59:59
);

插入和查询,可以看出来这个WHERE created_time = 1535731180的查询只是去p201808分区去找

insert into article_range values(null,'MySQL优化','内容示例',1535731180);
flush tables;
EXPLAIN SELECT * FROM `article_range` WHERE created_time = 1535731180
image.png

1、分区字段:表示要按照哪个字段进行分区,可以是一个字段名,也可以是对某个字段进行表达式运算如year(create_time),使用range最终的值必须是数字

2、分区名称: 要保证不同,也可以采用 p0、p1、p2 这样的分区名称,

3、less than : 表示小于
Value : 表示要小于某个具体的值,如 less than (10) 那么分区字段的值小于10的都会被分到这个分区

4、maxvalue: 表示一个最大的值

注意:range 对应的分区键值必须是数字值,可以使用range columns(分区字段) 对非int型做分区,如字符串,对于日期类型的可以使用year()、to_days()、to_seconds()等函数

LIST 分区:

也是一种条件分区,按照列表值分区(in (值列表))。这里是使用状态 字段来进行分区的。

create table article_list(
    id int auto_increment,
    title varchar(64),
    content text,
    status TINYINT(1),  -- 文章状态:0-草稿,1-完成但未发布,2-已发布
    PRIMARY KEY (id,status) -- 要求分区依据字段必须是主键的一部分
)charset=utf8
PARTITION BY list(status)(
    PARTITION writing values in(0,1),   -- 未发布的放在一个分区   
    PARTITION published values in (2)   -- 已发布的放在一个分区
);

插入数据和查询

insert into article_list values(null,'mysql优化','内容示例',0);
flush tables;
EXPLAIN SELECT * FROM article_list WHERE status = 1
image.png

WHERE status = 1查询只扫描 writing分区,而不是扫描所有分区。这对性能来讲肯定是有帮助的!

HASH分区:

相同的输入得到相同的输出。输出的结果跟输入是否具有规律无关。仅适用于整型字段;Hash分区的意义主要用于确保数据在预先确定数目的分区中追求平均分配。Hash分区会自动根据列计算需要插入的数据分布与那个分区。其使用的是hash分区键,然后根据分区的数量计算需要操作的分区。对于开发人员而言,要做的事情只是基于将要被哈希的列值指定一个表达式,以及指定被分区的表将要被分割的分区数量。具体使用如下:

CREATE TABLE shareniu_range3 ( id INT NOT NULL, NAME VARCHAR ( 50 ), age INT ) PARTITION BY HASH ( id ) PARTITIONS 3;
EXPLAIN SELECT * FROM shareniu_range3 WHERE id = 1

使用注意事项:

(1) 由于哈希分区每次更新、插入、删除一行数据,这个表达式都需要去计算一次,那就意味着非常复杂的表达式可能引擎性能的问题。尤其是在执行批量插入语句的时候。

(2) 最有效的哈希函数是只针对单个列进行计算,这个列的值最好随着列值进行增加,比如上述例子中使用的是int类型的列,这样哈希之后的数据分布的更加的均匀。因为这考虑了在分区范围内的修建,也就是说表达式值和他基于的列的值变化越接近,就更有效地使用该表达式进行哈希分区。

线性Hash分区

线性哈希分区在partition by子句中添加linear关键字即可。线性哈希分区的优点在于 增加、删除、合并和拆分分区将变得更加快捷。有利于处理及其大量的数据的表,缺点在于数据可能分布的不太均匀。

CREATE TABLE shareniu_range3 ( id INT NOT NULL, NAME VARCHAR ( 50 ), age INT ) PARTITION BY LINEAR HASH ( id ) PARTITIONS 3;
EXPLAIN SELECT * FROM shareniu_range3 WHERE id = 1
KEY分区

和hash(field)的性质一样,只不过key是处理字符串的,比hash()多了一步从字符串中计算出一个整型在做取模操作。

create table article_key(
    id int auto_increment,
    title varchar(64),
    content text,
    PRIMARY KEY (id,title)  -- 要求分区依据字段必须是主键的一部分
)PARTITION by KEY(title) PARTITIONS 10
columns分区

COLUMN分区是5.5开始引入的分区功能,只有RANGE COLUMN和LIST COLUMN这两种分区;支持整形、日期、字符串;RANGE和LIST的分区方式非常的相似。

COLUMNS和RANGE和LIST分区的区别
1、针对日期字段的分区就不需要再使用函数进行转换了,例如针对date字段进行分区不需要再使用YEAR()表达式进行转换。
2、COLUMN分区支持多个字段作为分区键但是不支持表达式作为分区键。

RANGE COLUMNS和LIST COLUMNS分区其实是RANG和LIST分区的升级,所以可以直接使用COLUMN分区。注意COLUMNS分区不支持timestamp字段类型。

COLUMNS支持的类型
整形支持:tinyint,smallint,mediumint,int,bigint;不支持decimal和float
时间类型支持:date,datetime
字符类型支持:char,varchar,binary,varbinary;不支持text,blob

比如: 日期COLUMNS分区

CREATE TABLE members (
    id INT,
    joined DATE NOT NULL
)
PARTITION BY RANGE COLUMNS(joined) (
    PARTITION a VALUES LESS THAN ('1960-01-01'),
    PARTITION b VALUES LESS THAN ('1970-01-01'),
    PARTITION c VALUES LESS THAN ('1980-01-01'),
    PARTITION d VALUES LESS THAN ('1990-01-01'),
    PARTITION e VALUES LESS THAN MAXVALUE
);

insert into members(id,joined) values(1,'1950-01-01'),(1,'1960-01-01'),(1,'1980-01-01'),(1,'1990-01-01');

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

推荐阅读更多精彩内容

  • 分区是指根据一定的规则,数据库把一个表分解成多个更小的,更容易管理的部分。就访问数据库的应用而言,逻辑上只有一个表...
    微日月阅读 1,496评论 0 7
  • pyspark.sql模块 模块上下文 Spark SQL和DataFrames的重要类: pyspark.sql...
    mpro阅读 9,451评论 0 13
  • MySQL从5.1版本开始支持分区功能,它允许可设置的一定逻辑,跨文件系统分配单个表的多个部分,但是就访问数据库而...
    仔仔H阅读 3,014评论 0 1
  • mysql分区 Mysql支持水平分区,并不支持垂直分区;水平分区:指将同一表中不同行的记录分配到不同的物理文件中...
    Gundy_阅读 907评论 0 2
  • 分区: 分区的功能不是在存储引擎层实现的。因此不只是InnoDB才支持分区。MyISAM、NDB都支持分区操作。 ...
    4ea0af17fd67阅读 1,768评论 0 0