介紹
RANGE分區基於一個給定的連續區間范圍,早期版本RANGE主要是基於整數的分區。在5.7版本中DATE、DATETIME列也可以使用RANGE分區,同時在5.5以上的版本提供了基於非整形的RANGE COLUMN分區。RANGE分區必須的連續的且不能重疊。使用
“VALUES LESS THAN ()”
來定義分區區間,非整形的范圍值需要使用單引號,並且可以使用MAXVALUE作為分區的最高值。
一、RANGE分區
1.創建分區
CREATE TABLE employees ( id INT NOT NULL, fname VARCHAR(30), lname VARCHAR(30), hired DATE NOT NULL DEFAULT '1970-01-01', separated DATE NOT NULL DEFAULT '9999-12-31', job_code INT NOT NULL, store_id INT NOT NULL ) PARTITION BY RANGE (store_id) ( PARTITION p0 VALUES LESS THAN (6), PARTITION p1 VALUES LESS THAN (11), PARTITION p2 VALUES LESS THAN (16), PARTITION p3 VALUES LESS THAN (21) );
alter table employees add index ix_store_id(store_id) ;
alter table employees add index ix_job_code(job_code) ;
p0:指分區p0,這個分區名的取值可以隨便取值只要同一個表里面的每個分區名不重復即可,也不需要非得從0開始,你也可以使用a、b、c、d。
THEN():分區的范圍值,這個值只能的連續不重疊的從小到大的值。
2.性能分析
插入測試數據
insert into employees(id,job_code,store_id) values(1,1001,1),(2,1002,2),(3,1003,3),(4,1004,4);
從執行計划可以看到兩個查詢都用到了分區的效果;如果細心估計會發現第二個查詢沒有走索引,並不是使用小於就不會走索引而且執行計划分析評估任務不走索引的效果會更好,事實卻是如果當前查詢整個分區的數據時使用索引的話還需要去查詢其它的字段還不如直接掃描整個分區來的快。
3.增加分區
由於當前分區值的范圍是小於21,當向分區表中插入一個超過分區范圍的值時會報錯。這個時候可以增加一個分區,當你不確定需要給一個多大的上限值時可以使用MAXVALUE
alter table employees add PARTITION (PARTITION p4 VALUES LESS THAN MAXVALUE);
注意:增加分區只能在最大端增加
4.刪除分區
alter table employees drop PARTITION p4;
注意:通過這種刪除分區的方式會將分區中的數據也刪除,慎用!!!!。但是通過刪除分區的方式刪除數據會比delete快很多,因為它相當於刪除一個數據庫一樣因為每個分區都是一個獨立的數據文件。用來刪除歷史分區數據是非常好的辦法。
5.拆分合並分區
拆分合並分區統稱為重新定義分區,拆分分為不會造成數據的丟失,只將會將數據從一個分區移動到另一個分區。
例1:將P0拆分成s1,s2兩個分區
ALTER TABLE employees REORGANIZE PARTITION p0 INTO ( PARTITION s0 VALUES LESS THAN (3), PARTITION s1 VALUES LESS THAN (6) );
注意:原來分區p0的范圍是[負無窮-6),所以新拆分的分區也必須是這范圍,所以新的分區范圍值最大不能超過6。
分區由原來的p0[-6)變成了so[-3),s1[3-6),整個分區的范圍還是不變。
例2:將s1,p1,p2合並為a,b兩個分區
ALTER TABLE employees REORGANIZE PARTITION s1,p1,p2 INTO ( PARTITION a VALUES LESS THAN (5), PARTITION b VALUES LESS THAN (16) );
原本的s1,p1,p2分區范圍是:[3-16)所以新的分區也必須和原本的分區相同,所以新的分區的值不能低於3不能高於16即可。
分區由原來的s1[3-6),p1[6-11),p2[11-16)變成了現在的a[3-5),b[5-16),總的范圍沒有發生變化
注意:無論是拆分還是合並分區都不能改變分區原本的覆蓋范圍,並且合並分區只能合並連續的分區不能跳過分區合並;並且不能改變分區的類型,例如不能把range分區改成key分區等。
二、日期字段分區方法
注意:RANG分區針對日期字段進行分區可以使用時間類型的函數進行轉換成整形,但是如果你的查詢語句需要利用分區那么查詢語句也需要使用相同的時間函數進行查詢。
1.使用YEAR()函數進行分區
CREATE TABLE employees1 ( id INT NOT NULL, fname VARCHAR(30), lname VARCHAR(30), hired DATE NOT NULL DEFAULT '1970-01-01', separated DATE NOT NULL DEFAULT '9999-12-31', job_code INT, store_id INT ) PARTITION BY RANGE ( YEAR(separated) ) ( PARTITION p0 VALUES LESS THAN (1991), PARTITION p1 VALUES LESS THAN (1996), PARTITION p2 VALUES LESS THAN (2001), PARTITION p3 VALUES LESS THAN MAXVALUE );
插入測試數據
insert into employees1(id,separated,job_code,store_id) values(1,'1990-03-04',1001,1),(2,'1995-03-04',1002,2),(3,'1998-03-04',1003,3),(4,'2016-03-04',1004,4);
對於日期字段分區,查詢條件使用> 、< 、betnwen、=都會利用分區查詢,如果條件使用函數轉換則不會走分區,比如使用YEAR()。
2.TIMESTAMP類型的列的分區方法
針對TIMESTAMP的日期類型的字段需要使用專門的
UNIX_TIMESTAMP()函數進行轉換
CREATE TABLE quarterly_report_status ( report_id INT NOT NULL, report_status VARCHAR(20) NOT NULL, report_updated TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ) PARTITION BY RANGE ( UNIX_TIMESTAMP(report_updated) ) ( PARTITION p0 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-01-01 00:00:00') ), PARTITION p1 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-04-01 00:00:00') ), PARTITION p2 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-07-01 00:00:00') ), PARTITION p3 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-10-01 00:00:00') ), PARTITION p4 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-01-01 00:00:00') ), PARTITION p5 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-04-01 00:00:00') ), PARTITION p6 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-07-01 00:00:00') ), PARTITION p7 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-10-01 00:00:00') ), PARTITION p8 VALUES LESS THAN ( UNIX_TIMESTAMP('2010-01-01 00:00:00') ), PARTITION p9 VALUES LESS THAN (MAXVALUE) );
三、null值處理
當往分區列中插入null值RANG 分區會將其當作最小值來處理即插入最小的分區中
CREATE TABLE test ( id INT NOT NULL, store_id INT ) PARTITION BY RANGE (store_id) ( PARTITION p0 VALUES LESS THAN (6), PARTITION p1 VALUES LESS THAN (11), PARTITION p2 VALUES LESS THAN (16), PARTITION p3 VALUES LESS THAN (21) ); insert into test(id,store_id) values(1,null);
SELECT PARTITION_NAME,PARTITION_METHOD,PARTITION_EXPRESSION,PARTITION_DESCRIPTION,TABLE_ROWS,SUBPARTITION_NAME,SUBPARTITION_METHOD,SUBPARTITION_EXPRESSION FROM information_schema.PARTITIONS WHERE TABLE_SCHEMA=SCHEMA() AND TABLE_NAME='test';
備注:文章中的示例摘自mysql官方參考手冊
四、移除表的分區
ALTER TABLE tablename
REMOVE PARTITIONING ;
注意:使用remove移除分區是僅僅移除分區的定義,並不會刪除數據和drop PARTITION不一樣,后者會連同數據一起刪除
分區系列文章:
RANGE分區:http://www.cnblogs.com/chenmh/p/5627912.html
LIST分區:http://www.cnblogs.com/chenmh/p/5643174.html
COLUMN分區:http://www.cnblogs.com/chenmh/p/5630834.html
HASH分區:http://www.cnblogs.com/chenmh/p/5644496.html
KEY分區:http://www.cnblogs.com/chenmh/p/5647210.html
子分區:http://www.cnblogs.com/chenmh/p/5649447.html
指定各分區路徑:http://www.cnblogs.com/chenmh/p/5644713.html
分區建索引:http://www.cnblogs.com/chenmh/p/5761995.html
分區介紹總結:http://www.cnblogs.com/chenmh/p/5623474.html
總結
有兩點非常重要需要注意,第一刪除分區時要慎重因為會連同分區里的數據一並刪除,拆分合並分區新的分區一定要和原來的分區的范圍一致。RANGE COLUMN分區單獨用章節進行講解,。
備注: 作者:pursuer.chen 博客:http://www.cnblogs.com/chenmh 本站點所有隨筆都是原創,歡迎大家轉載;但轉載時必須注明文章來源,且在文章開頭明顯處給明鏈接。 《歡迎交流討論》 |