当前位置:首页 > Mysql教程 > 列表

mysql partition 分区功能使用详解

发布:smiling 来源: PHP粉丝网  添加日期:2014-09-29 17:20:26 浏览: 评论:0 

= 最终结论 =

* 对于大数据量,建议使用分区功能.

* 去除不必要的字段.

* 根据手册,增加myisam_max_sort_file_size 会增加分区性能.

[分区命令详解],代码如下:

  1. = 分区例子 =  
  2. * RANGE 类型 
  3.  
  4. CREATE TABLE users ( 
  5.        uid INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY
  6.        name VARCHAR(30) NOT NULL DEFAULT ''
  7.        email VARCHAR(30) NOT NULL DEFAULT '' 
  8. PARTITION BY RANGE (uid) ( 
  9.        PARTITION p0 VALUES LESS THAN (3000000) 
  10.        DATA DIRECTORY = '/data0/data' 
  11.        INDEX DIRECTORY = '/data1/idx'
  12.  
  13.        PARTITION p1 VALUES LESS THAN (6000000) 
  14.        DATA DIRECTORY = '/data2/data' 
  15.        INDEX DIRECTORY = '/data3/idx'
  16.  
  17.        PARTITION p2 VALUES LESS THAN (9000000) 
  18.        DATA DIRECTORY = '/data4/data' 
  19.        INDEX DIRECTORY = '/data5/idx'
  20.  
  21.        PARTITION p3 VALUES LESS THAN MAXVALUE     DATA DIRECTORY = '/data6/data'  
  22.        INDEX DIRECTORY = '/data7/idx' 
  23. ); 

在这里,将用户表分成4个分区,以每300万条记录为界限,每个分区都有自己独立的数据、索引文件的存放目录,与此同时,这些目录所在的物理磁盘分区可能也都是完全独立的,可以提高磁盘IO吞吐量.

LIST 类型,代码如下:

  1. CREATE TABLE category ( 
  2.      cid INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY
  3.      name VARCHAR(30) NOT NULL DEFAULT '' 
  4. PARTITION BY LIST (cid) ( 
  5.      PARTITION p0 VALUES IN (0,4,8,12) 
  6.      DATA DIRECTORY = '/data0/data'  
  7.      INDEX DIRECTORY = '/data1/idx'
  8.       
  9.      PARTITION p1 VALUES IN (1,5,9,13) 
  10.      DATA DIRECTORY = '/data2/data' 
  11.      INDEX DIRECTORY = '/data3/idx'
  12.       
  13.      PARTITION p2 VALUES IN (2,6,10,14) 
  14.      DATA DIRECTORY = '/data4/data' 
  15.      INDEX DIRECTORY = '/data5/idx'
  16.       
  17.      PARTITION p3 VALUES IN (3,7,11,15) 
  18.      DATA DIRECTORY = '/data6/data' 
  19.      INDEX DIRECTORY = '/data7/idx' 
  20. ); 

分成4个区,数据文件和索引文件单独存放.

HASH 类型,代码如下:

  1. CREATE TABLE users ( 
  2.      uid INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY
  3.      name VARCHAR(30) NOT NULL DEFAULT ''
  4.      email VARCHAR(30) NOT NULL DEFAULT '' 
  5. PARTITION BY HASH (uid) PARTITIONS 4 ( 
  6.      PARTITION p0 
  7.      DATA DIRECTORY = '/data0/data' 
  8.      INDEX DIRECTORY = '/data1/idx'
  9.      --phpfensi.com 
  10.      PARTITION p1 
  11.      DATA DIRECTORY = '/data2/data' 
  12.      INDEX DIRECTORY = '/data3/idx'
  13.  
  14.      PARTITION p2 
  15.      DATA DIRECTORY = '/data4/data' 
  16.      INDEX DIRECTORY = '/data5/idx'
  17.  
  18.      PARTITION p3 
  19.      DATA DIRECTORY = '/data6/data' 
  20.      INDEX DIRECTORY = '/data7/idx' 
  21. ); 

分成4个区,数据文件和索引文件单独存放,例子,代码如下:

  1. CREATE TABLE ti2 (id INT, amount DECIMAL(7,2), tr_date DATE
  2.     ENGINE=myisam 
  3.     PARTITION BY HASH( MONTH(tr_date) ) 
  4.     PARTITIONS 6; 
  5.  
  6. CREATE PROCEDURE load_ti2() 
  7.        begin 
  8.     declare v int default 0; 
  9.     while v < 80000 
  10.     do 
  11.         insert into ti2 
  12.         values (v,'3.14',adddate('1995-01-01',(rand(v)*3652) mod 365)); 
  13.          set v = v + 1; 
  14.     end while; 
  15.     end 
  16.     // 

KEY 类型,代码如下:

  1. CREATE TABLE users ( 
  2.      uid INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY
  3.      name VARCHAR(30) NOT NULL DEFAULT ''
  4.      email VARCHAR(30) NOT NULL DEFAULT '' 
  5. PARTITION BY KEY (uid) PARTITIONS 4 ( 
  6.      PARTITION p0 
  7.      DATA DIRECTORY = '/data0/data' 
  8.      INDEX DIRECTORY = '/data1/idx'
  9.       
  10.      PARTITION p1 
  11.      DATA DIRECTORY = '/data2/data'  
  12.      INDEX DIRECTORY = '/data3/idx'
  13.       
  14.      PARTITION p2  
  15.      DATA DIRECTORY = '/data4/data' 
  16.      INDEX DIRECTORY = '/data5/idx'
  17.       
  18.      PARTITION p3  
  19.      DATA DIRECTORY = '/data6/data' 
  20.      INDEX DIRECTORY = '/data7/idx' 
  21. ); 

分成4个区,数据文件和索引文件单独存放.

子分区:子分区是针对 RANGE/LIST 类型的分区表中每个分区的再次分割,再次分割可以是 HASH/KEY 等类型,例如,代码如下:

  1. CREATE TABLE users ( 
  2.      uid INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY
  3.      name VARCHAR(30) NOT NULL DEFAULT ''
  4.      email VARCHAR(30) NOT NULL DEFAULT '' 
  5. PARTITION BY RANGE (uid) SUBPARTITION BY HASH (uid % 4) SUBPARTITIONS 2( 
  6.      PARTITION p0 VALUES LESS THAN (3000000) 
  7.      DATA DIRECTORY = '/data0/data' 
  8.      INDEX DIRECTORY = '/data1/idx'
  9.  
  10.      PARTITION p1 VALUES LESS THAN (6000000) 
  11.      DATA DIRECTORY = '/data2/data' 
  12.      INDEX DIRECTORY = '/data3/idx' 
  13. ); 

对 RANGE 分区再次进行子分区划分,子分区采用 HASH 类型,或者如下代码:

  1. CREATE TABLE users ( 
  2.      uid INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY
  3.      name VARCHAR(30) NOT NULL DEFAULT ''
  4.      email VARCHAR(30) NOT NULL DEFAULT '' 
  5. PARTITION BY RANGE (uid) SUBPARTITION BY KEY(uid) SUBPARTITIONS 2( 
  6.      PARTITION p0 VALUES LESS THAN (3000000) 
  7.      DATA DIRECTORY = '/data0/data' 
  8.      INDEX DIRECTORY = '/data1/idx'
  9.  
  10.      PARTITION p1 VALUES LESS THAN (6000000) 
  11.      DATA DIRECTORY = '/data2/data' 
  12.      INDEX DIRECTORY = '/data3/idx' 
  13. ); 

对 RANGE 分区再次进行子分区划分,子分区采用 KEY 类型.

分区管理:

删除分区:ALERT TABLE users DROP PARTITION p0;,删除分区 p0。

重建分区,o RANGE 分区重建:ALTER TABLE users REORGANIZE PARTITION p0,p1 INTO (PARTITION p0 VALUES LESS THAN (6000000));将原来的 p0,p1 分区合并起来,放到新的 p0 分区中.

o LIST 分区重建:ALTER TABLE users REORGANIZE PARTITION p0,p1 INTO (PARTITION p0 VALUES IN(0,1,4,5,8,9,12,13));

将原来的 p0,p1 分区合并起来,放到新的 p0 分区中,o HASH/KEY 分区重建,ALTER TABLE users REORGANIZE PARTITION COALESCE PARTITION 2;

用 REORGANIZE 方式重建分区的数量变成2,在这里数量只能减少不能增加。想要增加可以用 ADD PARTITION 方法。

新增分区,o 新增 RANGE 分区:ALTER TABLE category ADD PARTITION (PARTITION p4 VALUES IN (16,17,18,19)

DATA DIRECTORY = '/data8/data'

INDEX DIRECTORY = '/data9/idx');

新增一个RANGE分区,o 新增 HASH/KEY 分区:ALTER TABLE users ADD PARTITION PARTITIONS 8;将分区总数扩展到8个.

给已有的表加上分区,代码如下:

  1. alter table results partition by RANGE (month(ttime))  
  2. (PARTITION p0 VALUES LESS THAN (1), 
  3. PARTITION p1 VALUES LESS THAN (2) , PARTITION p2 VALUES LESS THAN (3) , 
  4. PARTITION p3 VALUES LESS THAN (4) , PARTITION p4 VALUES LESS THAN (5) , 
  5. PARTITION p5 VALUES LESS THAN (6) , PARTITION p6 VALUES LESS THAN (7) , 
  6. PARTITION p7 VALUES LESS THAN (8) , PARTITION p8 VALUES LESS THAN (9) , 
  7. PARTITION p9 VALUES LESS THAN (10) , PARTITION p10 VALUES LESS THAN (11), 
  8. PARTITION p11 VALUES LESS THAN (12), 
  9. PARTITION P12 VALUES LESS THAN (13) ); 

默认分区限制分区字段必须是主键,PRIMARY KEY)的一部分,为了去除此限制.

方法1,使用ID,代码如下:

  1. mysql> ALTER TABLE np_pk 
  2.     ->     PARTITION BY HASH( TO_DAYS(added) ) 
  3.     ->     PARTITIONS 4; 
  4. ERROR 1503 (HY000): A PRIMARY KEY must include all columns in the table's partitioning function 
  5.  
  6. However, this statement using the id column for the partitioning column is valid, as shown here: 
  7.  
  8. mysql> ALTER TABLE np_pk 
  9.     ->     PARTITION BY HASH(id) 
  10.     ->     PARTITIONS 4; 
  11. Query OK, 0 rows affected (0.11 sec) 
  12. Records: 0 Duplicates: 0 Warnings: 0 

方法2,将原有PK去掉生成新PK,代码如下:

  1. mysql> alter table results drop PRIMARY KEY
  2. Query OK, 5374850 rows affected (7 min 4.05 sec) 
  3. Records: 5374850 Duplicates: 0 Warnings: 0 
  4.  
  5. mysql> alter table results add PRIMARY KEY(id, ttime); 
  6. Query OK, 5374850 rows affected (6 min 14.86 sec) 
  7. Records: 5374850 Duplicates: 0 Warnings: 0

Tags: partition mysql分区功能

分享到:

相关文章