一 分區表適用於如下場景html
1:表很是大以致於沒法所有放在內存中,或者只在標的最後部分有熱點數據,其餘均是歷史數據node
2:分區表的數據更容易維護。例如想批量刪除大量數據可使用清除整個分區的方式。另外還能夠對一個獨立分區進行優化、檢查、修復等操做。mysql
3:分區表的數據能夠分佈在不一樣的物理設備上,從而高效的利用多個硬件設備sql
4:可使用分區表來避免某些特殊的瓶頸。例如InnoDB的單個索引的互斥訪問、ext3文件系統的inode鎖競爭等。數據庫
5:若是須要,還能夠備份和恢復獨立的分區,這在很是大的數據集的場景下效果很是好。less
二 分區原理以及限制post
mysql數據庫中的數據是以文件的形勢存在磁盤上的,默認放在/mysql/data下面(能夠經過my.cnf中的datadir來查看),一張表主要對應着三個文件,一個是frm存放表結構的,一個是myd存放表數據的,
一個是myi存表索引的。若是一張表的數據量太大的話,那麼myd,myi就會變的很大,查找數據就會變的很慢,這個時候咱們能夠利用mysql的分區功能,
在物理上將這一張表對應的三個文件,分割成許多個小塊,這樣呢,咱們查找一條數據時,就不用所有查找了,只要知道這條數據在哪一塊,而後在那一塊找就好了。
若是表的數據太大,可能一個磁盤放不下,這個時候,咱們能夠把數據分配到不一樣的磁盤裏面去。優化
分區表的限制ui
分區表的原理url
SELECT 查詢:當查詢一個分區表的時候,分區層先打開並鎖住全部底層表,優化器先判斷是否能夠過濾部分分區,而後再調用對應的存儲引擎接口訪問各個分區的數據;
INSERT操做:當寫入一條數據時,分區層先打開並鎖住全部的底層表,而後肯定那個分區接收這條數據,而後再將記錄寫入對應的底層表;
DELETE操做:當刪除一條記錄時,分區層現代開並鎖住全部的底層表,而後肯定數據對應的分區,最後對相應底層進行刪除操做;
UPDATE操做:當更新一條記錄時,分區層先打開並鎖住全部的底層表,MYSQL先肯定須要更新的記錄在哪一個分區,而後取出數據並更新,在判斷更新後的數據應該放在哪一個分區,最後對底層表進行寫入操做,並對原數據所在的底層表進行刪除操做。
固然其中有些操做是支持過濾的。例如當刪除一條記錄時,MYSQL 須要先找到這條記錄,若是where條件剛好和分區表達式匹配,就能夠將全部不包含這條記錄的分區都過濾掉。一樣的操做對於update一樣有效。若是是insert操做,其自己就是隻命中一個分區 ,其餘分區都會被過濾掉。MYSQL先肯定這條記錄屬於哪一個分區,再將記錄寫入對應的底層分區表,無須對任何其餘分區進行操做。(雖然每一個操做都會「」「先打開並鎖住全部的底層表」,可是並非說分區表在處理過程當中是鎖住全表的,若是存儲引擎可以本身實現行級鎖,例如InnoDB,則會在分區層釋放對應表鎖)。
分區表的類型:MYSQL支持多種分區表
最多見的就是根據範圍進行分區,每一個分區存儲落在某個範圍的記錄,分區表達式能夠是列,也能夠是列的表達式。下面的例子是將每年的銷售額存放在不一樣的分區裏。
子分區是分區表中每一個分區的再次分割,子分區既可使用HASH希分區,也可使用KEY分區。這 也被稱爲複合分區(composite partitioning)
1. 若是一個分區中建立了子分區,其餘分區也要有子分區
2. 若是建立了了分區,每一個分區中的子分區數必有相同
3. 同一分區內的子分區,名字不相同,不一樣分區內的子分區名子能夠相同(5.1.50不適用)
1
2
3
4
5
6
7
8
9
10
11
12
13
|
mysql> CREATE TABLE IF NOT EXISTS `sub_part` (
-> `news_id` int(11) NOT NULL COMMENT '新聞ID',
-> `content` varchar(1000) NOT NULL DEFAULT '' COMMENT '新聞內容',
-> `u_id` int(11) NOT NULL DEFAULT 0s COMMENT '來源IP',
-> `create_time` DATE NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '時間'
-> ) ENGINE=INNODB DEFAULT CHARSET=utf8
-> PARTITION BY RANGE(YEAR(create_time))
-> SUBPARTITION BY HASH(TO_DAYS(create_time))(
-> PARTITION p0 VALUES LESS THAN (1990)(SUBPARTITION s0,SUBPARTITION s1,SUBPARTITION s2),
-> PARTITION p1 VALUES LESS THAN (2000)(SUBPARTITION s3,SUBPARTITION s4,SUBPARTITION good),
-> PARTITION p2 VALUES LESS THAN MAXVALUE(SUBPARTITION tank0,SUBPARTITION tank1,SUBPARTITION tank3)
-> );
Query OK, 0 rows affected (0.07 sec)
|
增長分區操做(針對設置MAXVALUE)
range添加分區
1
2
3
|
mysql>alter table operation_log add partition(partition `2013-10` values less than (1383235200)); --->適用於沒有設置MAXVALUE的分區添加
ERROR 1481 (HY000):MAXVALUE can only be used in last partition definition
mysql>alter table operation_log REORGANIZE partition `2013-09` into (partition `2013-09` values less than (1380556800),partition `2013-10` values less than (1383235200),partition `2013-11` values less than maxvalue);
|
list添加分區
1
2
3
|
mysql> alter table list_part add partition(partition p4 values in (25,26,28));
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
|
hash從新分區
1
2
3
|
mysql> alter table list_part add partition(partition p4 values in (25,26,28));
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
|
key從新分區
1
2
3
|
mysql> alter table key_part add partition partitions 4;
Query OK, 1 row affected (0.06 sec)//有數據也會被從新分配
Records: 1 Duplicates: 0 Warnings: 0
|
子分區添加新分區,雖然我沒有指定子分區,可是系統會給子分區命名的
1
2
3
|
mysql> alter table sub1_part add partition(partition p3 values less than MAXVALUE);
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
|
alter table user drop partition
2013-05;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
重建分區(官方:與先drop全部記錄而後reinsert是同樣的效果;用於整理表碎片)
alter table operation_log rebuild partition `2014-01`;
重建多個分區
alter table operation_log rebuild partition `2014-01`,`2014-02`;
過程以下:
pro
優化分區(若是刪除了一個分區的大量記錄或者對一個分區的varchar blob text數據類型的字段作了許多更新,此時能夠對分區進行優化以回收未使用的空間和整理分區數據文件)
alter table operation_log optimize partition `2014-01`;
優化的操做至關於check partition,analyze partition 和repair patition
分析分區
alter table operation_log analyze partition `2014-01`;
修復分區
alter table operation_log repair partition `2014-01`;
檢查分區
alter table operation_log check partition `2014-01`;
|