分區(qū)依據(jù)的字段必須是主鍵/唯一索引的組成部分
碱呼,分區(qū)是為了快速定位數(shù)據(jù)于未,因此該字段的搜索頻次較高應(yīng)作為強(qiáng)檢索字段冠绢,否則依照該字段分區(qū)毫無意義
mysql為我們提供的分區(qū)方法有下列幾種
一雁刷、range泽艘、list
二、hash台谍、key
三须喂、columns
RANGE 分區(qū):
按照數(shù)據(jù)大小范圍分區(qū)(將數(shù)據(jù)使用某種條件,分散到不同的分區(qū)中)。如下坞生,按文章的發(fā)布時(shí)間將數(shù)據(jù)按照2018年8月仔役、9月、10月分區(qū)存放:
create table article_range(
id int auto_increment,
title varchar(64),
content text,
created_time int, -- 發(fā)布時(shí)間到1970-1-1的毫秒數(shù)
PRIMARY KEY (id,created_time) -- 要求分區(qū)依據(jù)字段必須是主鍵的一部分
)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
);
插入和查詢是己,可以看出來這個(gè)WHERE created_time = 1535731180的查詢只是去p201808
分區(qū)去找
insert into article_range values(null,'MySQL優(yōu)化','內(nèi)容示例',1535731180);
flush tables;
EXPLAIN SELECT * FROM `article_range` WHERE created_time = 1535731180
1又兵、分區(qū)字段:表示要按照哪個(gè)字段進(jìn)行分區(qū),可以是一個(gè)字段名卒废,也可以是對某個(gè)字段進(jìn)行表達(dá)式運(yùn)算如year(create_time)寒波,使用range最終的值必須是數(shù)字
2、分區(qū)名稱: 要保證不同升熊,也可以采用 p0、p1绸栅、p2 這樣的分區(qū)名稱级野,
3、less than : 表示小于
Value : 表示要小于某個(gè)具體的值粹胯,如 less than (10) 那么分區(qū)字段的值小于10的都會(huì)被分到這個(gè)分區(qū)
4蓖柔、maxvalue: 表示一個(gè)最大的值
注意:range 對應(yīng)的分區(qū)鍵值必須是數(shù)字值,可以使用range columns(分區(qū)字段) 對非int型做分區(qū)风纠,如字符串况鸣,對于日期類型的可以使用year()、to_days()竹观、to_seconds()等函數(shù)
LIST 分區(qū):
也是一種條件分區(qū)镐捧,按照列表值分區(qū)(in (值列表))。這里是使用狀態(tài)
字段來進(jìn)行分區(qū)的臭增。
create table article_list(
id int auto_increment,
title varchar(64),
content text,
status TINYINT(1), -- 文章狀態(tài):0-草稿懂酱,1-完成但未發(fā)布,2-已發(fā)布
PRIMARY KEY (id,status) -- 要求分區(qū)依據(jù)字段必須是主鍵的一部分
)charset=utf8
PARTITION BY list(status)(
PARTITION writing values in(0,1), -- 未發(fā)布的放在一個(gè)分區(qū)
PARTITION published values in (2) -- 已發(fā)布的放在一個(gè)分區(qū)
);
插入數(shù)據(jù)和查詢
insert into article_list values(null,'mysql優(yōu)化','內(nèi)容示例',0);
flush tables;
EXPLAIN SELECT * FROM article_list WHERE status = 1
WHERE status = 1查詢只掃描 writing分區(qū)誊抛,而不是掃描所有分區(qū)列牺。這對性能來講肯定是有幫助的!
HASH分區(qū):
相同的輸入得到相同的輸出拗窃。輸出的結(jié)果跟輸入是否具有規(guī)律無關(guān)瞎领。僅適用于整型字段
;Hash分區(qū)的意義主要用于確保數(shù)據(jù)在預(yù)先確定數(shù)目的分區(qū)中追求平均分配
随夸。Hash分區(qū)會(huì)自動(dòng)根據(jù)列計(jì)算需要插入的數(shù)據(jù)分布與那個(gè)分區(qū)九默。其使用的是hash分區(qū)鍵,然后根據(jù)分區(qū)的數(shù)量計(jì)算需要操作的分區(qū)逃魄。對于開發(fā)人員而言荤西,要做的事情只是基于將要被哈希的列值指定一個(gè)表達(dá)式,以及指定被分區(qū)的表將要被分割的分區(qū)數(shù)量。具體使用如下:
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
使用注意事項(xiàng):
(1) 由于哈希分區(qū)每次更新邪锌、插入勉躺、刪除一行數(shù)據(jù),這個(gè)表達(dá)式都需要去計(jì)算一次觅丰,那就意味著非常復(fù)雜的表達(dá)式可能引擎性能的問題饵溅。尤其是在執(zhí)行批量插入語句的時(shí)候。
(2) 最有效的哈希函數(shù)是只針對單個(gè)列進(jìn)行計(jì)算妇萄,這個(gè)列的值最好隨著列值進(jìn)行增加蜕企,比如上述例子中使用的是int類型的列,這樣哈希之后的數(shù)據(jù)分布的更加的均勻冠句。因?yàn)檫@考慮了在分區(qū)范圍內(nèi)的修建轻掩,也就是說表達(dá)式值和他基于的列的值變化越接近,就更有效地使用該表達(dá)式進(jìn)行哈希分區(qū)懦底。
線性Hash分區(qū)
線性哈希分區(qū)在partition by子句中添加linear
關(guān)鍵字即可唇牧。線性哈希分區(qū)的優(yōu)點(diǎn)在于 增加、刪除聚唐、合并和拆分分區(qū)將變得更加快捷丐重。有利于處理及其大量的數(shù)據(jù)的表,缺點(diǎn)在于數(shù)據(jù)可能分布的不太均勻杆查。
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分區(qū)
和hash(field)的性質(zhì)一樣扮惦,只不過key是處理字符串
的,比hash()多了一步從字符串中計(jì)算出一個(gè)整型在做取模操作亲桦。
create table article_key(
id int auto_increment,
title varchar(64),
content text,
PRIMARY KEY (id,title) -- 要求分區(qū)依據(jù)字段必須是主鍵的一部分
)PARTITION by KEY(title) PARTITIONS 10
columns分區(qū)
COLUMN分區(qū)是5.5開始引入的分區(qū)功能崖蜜,只有RANGE COLUMN和LIST COLUMN這兩種分區(qū);支持整形客峭、日期纳猪、字符串;RANGE和LIST的分區(qū)方式非常的相似桃笙。
COLUMNS和RANGE和LIST分區(qū)的區(qū)別
1氏堤、針對日期字段的分區(qū)就不需要再使用函數(shù)進(jìn)行轉(zhuǎn)換了,例如針對date字段進(jìn)行分區(qū)不需要再使用YEAR()表達(dá)式進(jìn)行轉(zhuǎn)換搏明。
2鼠锈、COLUMN分區(qū)支持多個(gè)字段作為分區(qū)鍵但是不支持表達(dá)式作為分區(qū)鍵。
RANGE COLUMNS和LIST COLUMNS分區(qū)其實(shí)是RANG和LIST分區(qū)的升級星著,所以可以直接使用COLUMN分區(qū)购笆。注意COLUMNS分區(qū)不支持timestamp字段類型。
COLUMNS支持的類型
整形支持:tinyint,smallint,mediumint,int,bigint;不支持decimal和float
時(shí)間類型支持:date,datetime
字符類型支持:char,varchar,binary,varbinary;不支持text,blob
比如: 日期COLUMNS分區(qū)
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'