改变一个表的分区方案只需使用alter table 加 partition_options 子句就可以了。和创建分区表时的create table语句很像

创建表

CREATE TABLE trb3 (id INT, name VARCHAR(50), purchased DATE)
    PARTITION BY RANGE( YEAR(purchased) ) (
        PARTITION p0 VALUES LESS THAN (1990),
        PARTITION p1 VALUES LESS THAN (1995),
        PARTITION p2 VALUES LESS THAN (2000),
        PARTITION p3 VALUES LESS THAN (2005)
    );

创建插入数据存储过程

delimiter $$
drop procedure if exists pr_trb3$$
create procedure pr_trb3(in begindate date,in enddate date,in tabname varchar(40))
begin
    while begindate<enddate
    do
        set @s=concat_ws(' ','insert into',tabname,'values(1,''fanboshi'',''',begindate,''')');
        prepare stmt from @s;
        execute stmt;
        drop prepare stmt;
        set begindate = date_add(begindate,interval 1 day);
    end while;
end$$

delimiter ;

调用存储过程插入数据

call pr_trb3('1985-01-01','2004-12-31','trb3');

查看数据分布

select
  partition_name part,
  partition_expression expr,
  partition_description descr,
  table_rows
from information_schema.partitions  where
  table_schema = schema()
  and table_name='trb3';
+------+------------------+-------+------------+
| part | expr             | descr | table_rows |
+------+------------------+-------+------------+
| p0   |  YEAR(purchased) | 1990  |       1826 |
| p1   |  YEAR(purchased) | 1995  |       1826 |
| p2   |  YEAR(purchased) | 2000  |       1826 |
| p3   |  YEAR(purchased) | 2005  |       1826 |
+------+------------------+-------+------------+
4 rows in set (0.00 sec)

改变分区方案

mysql> ALTER TABLE trb3 PARTITION BY KEY(id) PARTITIONS 4;
Query OK, 7304 rows affected (0.07 sec)
Records: 7304  Duplicates: 0  Warnings: 0

查看数据

select
  partition_name part,
  partition_expression expr,
  partition_description descr,
  table_rows
from information_schema.partitions  where
  table_schema = schema()
  and table_name='trb3';
+------+------+-------+------------+
| part | expr | descr | table_rows |
+------+------+-------+------------+
| p0   | `id` | NULL  |       7472 |
| p1   | `id` | NULL  |          0 |
| p2   | `id` | NULL  |          0 |
| p3   | `id` | NULL  |          0 |
+------+------+-------+------------+
4 rows in set (0.00 sec)

mysql> select 1826*4;
+--------+
| 1826*4 |
+--------+
|   7304 |
+--------+
1 row in set (0.00 sec)

count(*)行数一致,说明数据没出问题,但是information_schema.partitions查出来的不对,这就不知道为什么了

For partitioned InnoDB tables, the row count given in the TABLE_ROWS column of the INFORMATION_SCHEMA.PARTITIONS table is only an estimated value used in SQL optimization, and is not always exact.

mysql> select count(*) from trb3;
+----------+
| count(*) |
+----------+
|     7304 |
+----------+
但是count(*)还是7304,什么鬼

再次改变分区方案

ALTER TABLE trb3
    PARTITION BY RANGE( YEAR(purchased) ) (
        PARTITION p0 VALUES LESS THAN (1990),
        PARTITION p1 VALUES LESS THAN (1995),
        PARTITION p2 VALUES LESS THAN (2000),
        PARTITION p3 VALUES LESS THAN (2005)
    );

mysql> select
    ->   partition_name part,
    ->   partition_expression expr,
    ->   partition_description descr,
    ->   table_rows
    -> from information_schema.partitions  where
    ->   table_schema = schema()
    ->   and table_name='trb3';
+------+------------------+-------+------------+
| part | expr             | descr | table_rows |
+------+------------------+-------+------------+
| p0   |  YEAR(purchased) | 1990  |       1826 |
| p1   |  YEAR(purchased) | 1995  |       1826 |
| p2   |  YEAR(purchased) | 2000  |          0 |
| p3   |  YEAR(purchased) | 2005  |          0 |
+------+------------------+-------+------------+
4 rows in set (0.00 sec)

丢数据了。。
更正,实际没丢,这个information_shcema.partitions表有延迟,过一会再查就好了

mysql> select
    ->   partition_name part,
    ->   partition_expression expr,
    ->   partition_description descr,
    ->   table_rows
    -> from information_schema.partitions  where
    ->   table_schema = schema()
    ->   and table_name='trb3';
+------+------------------+-------+------------+
| part | expr             | descr | table_rows |
+------+------------------+-------+------------+
| p0   |  YEAR(purchased) | 1990  |       1826 |
| p1   |  YEAR(purchased) | 1995  |       1826 |
| p2   |  YEAR(purchased) | 2000  |       1826 |
| p3   |  YEAR(purchased) | 2005  |       1826 |
+------+------------------+-------+------------+
4 rows in set (0.00 sec)

官方文档说:
This has the same effect on the structure of the table as dropping the table and re-creating it using CREATE TABLE trb3 PARTITION BY KEY(id) PARTITIONS 2;
就是说ALTER TABLE trb3 PARTITION BY与 drop table然后重新create table trb3 partition by key(id) partitions 2一样呢。

改存储引擎,和普通表没啥区别

mysql> drop table trb3;
Query OK, 0 rows affected (0.01 sec)

mysql> CREATE TABLE trb3 (id INT, name VARCHAR(50), purchased DATE)
    ->     PARTITION BY RANGE( YEAR(purchased) ) (
    ->         PARTITION p0 VALUES LESS THAN (1990),
    ->         PARTITION p1 VALUES LESS THAN (1995),
    ->         PARTITION p2 VALUES LESS THAN (2000),
    ->         PARTITION p3 VALUES LESS THAN (2005)
    ->     );
Query OK, 0 rows affected (0.03 sec)

mysql> call pr_trb3('1985-01-01','2004-12-31','trb3');
Query OK, 0 rows affected (1.69 sec)

mysql> select
    ->   partition_name part,
    ->   partition_expression expr,
    ->   partition_description descr,
    ->   table_rows
    -> from information_schema.partitions  where
    ->   table_schema = schema()
    ->   and table_name='trb3';
+------+------------------+-------+------------+
| part | expr             | descr | table_rows |
+------+------------------+-------+------------+
| p0   |  YEAR(purchased) | 1990  |       1826 |
| p1   |  YEAR(purchased) | 1995  |       1826 |
| p2   |  YEAR(purchased) | 2000  |       1826 |
| p3   |  YEAR(purchased) | 2005  |       1826 |
+------+------------------+-------+------------+
4 rows in set (0.01 sec)

mysql> alter table trb3 engine=myisam;
Query OK, 7304 rows affected (0.02 sec)
Records: 7304  Duplicates: 0  Warnings: 0

mysql> select
    ->   partition_name part,
    ->   partition_expression expr,
    ->   partition_description descr,
    ->   table_rows
    -> from information_schema.partitions  where
    ->   table_schema = schema()
    ->   and table_name='trb3';
+------+------------------+-------+------------+
| part | expr             | descr | table_rows |
+------+------------------+-------+------------+
| p0   |  YEAR(purchased) | 1990  |       1826 |
| p1   |  YEAR(purchased) | 1995  |       1826 |
| p2   |  YEAR(purchased) | 2000  |       1826 |
| p3   |  YEAR(purchased) | 2005  |       1826 |
+------+------------------+-------+------------+
4 rows in set (0.01 sec)

mysql> show create table trb3\G
*************************** 1. row ***************************
       Table: trb3
Create Table: CREATE TABLE `trb3` (
  `id` int(11) DEFAULT NULL,
  `name` varchar(50) DEFAULT NULL,
  `purchased` date DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8
/*!50100 PARTITION BY RANGE ( YEAR(purchased))
(PARTITION p0 VALUES LESS THAN (1990) ENGINE = MyISAM,
 PARTITION p1 VALUES LESS THAN (1995) ENGINE = MyISAM,
 PARTITION p2 VALUES LESS THAN (2000) ENGINE = MyISAM,
 PARTITION p3 VALUES LESS THAN (2005) ENGINE = MyISAM) */
1 row in set (0.00 sec)

将表由分区表改为非分区表

mysql> alter table trb3 remove partitioning;
Query OK, 7304 rows affected (0.01 sec)
Records: 7304  Duplicates: 0  Warnings: 0

mysql> select
    ->   partition_name part,
    ->   partition_expression expr,
    ->   partition_description descr,
    ->   table_rows
    -> from information_schema.partitions  where
    ->   table_schema = schema()
    ->   and table_name='trb3';
+------+------+-------+------------+
| part | expr | descr | table_rows |
+------+------+-------+------------+
| NULL | NULL | NULL  |       7304 |
+------+------+-------+------------+
1 row in set (0.00 sec)

mysql> show create table trb3\G
*************************** 1. row ***************************
       Table: trb3
Create Table: CREATE TABLE `trb3` (
  `id` int(11) DEFAULT NULL,
  `name` varchar(50) DEFAULT NULL,
  `purchased` date DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

Range List分区管理

mysql> drop table trb3;
Query OK, 0 rows affected (0.01 sec)

mysql> CREATE TABLE trb3 (id INT, name VARCHAR(50), purchased DATE)
    ->     PARTITION BY RANGE( YEAR(purchased) ) (
    ->         PARTITION p0 VALUES LESS THAN (1990),
    ->         PARTITION p1 VALUES LESS THAN (1995),
    ->         PARTITION p2 VALUES LESS THAN (2000),
    ->         PARTITION p3 VALUES LESS THAN (2005)
    ->     );
Query OK, 0 rows affected (0.03 sec)

mysql> call pr_trb3('1985-01-01','2004-12-31','trb3');
Query OK, 0 rows affected (1.75 sec)

mysql> select
    ->   partition_name part,
    ->   partition_expression expr,
    ->   partition_description descr,
    ->   table_rows
    -> from information_schema.partitions  where
    ->   table_schema = schema()
    ->   and table_name='trb3';
+------+------------------+-------+------------+
| part | expr             | descr | table_rows |
+------+------------------+-------+------------+
| p0   |  YEAR(purchased) | 1990  |       1826 |
| p1   |  YEAR(purchased) | 1995  |       1826 |
| p2   |  YEAR(purchased) | 2000  |       1826 |
| p3   |  YEAR(purchased) | 2005  |       1826 |
+------+------------------+-------+------------+
4 rows in set (0.00 sec)

增加分区

mysql> alter table trb3 add partition (partition p5 values less than(2010));
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

合并分区

mysql> alter table trb3 reorganize partition p3,p5 into(partition p5 values less than(2010));
Query OK, 1826 rows affected (0.03 sec)
Records: 1826  Duplicates: 0  Warnings: 0

mysql> select
    ->   partition_name part,
    ->   partition_expression expr,
    ->   partition_description descr,
    ->   table_rows
    -> from information_schema.partitions  where
    ->   table_schema = schema()
    ->   and table_name='trb3';
+------+------------------+-------+------------+
| part | expr             | descr | table_rows |
+------+------------------+-------+------------+
| p0   |  YEAR(purchased) | 1990  |       1826 |
| p1   |  YEAR(purchased) | 1995  |       1826 |
| p2   |  YEAR(purchased) | 2000  |       1826 |
| p5   |  YEAR(purchased) | 2010  |       1826 |
+------+------------------+-------+------------+
4 rows in set (0.00 sec)

分裂分区

mysql> ALTER TABLE trb3 REORGANIZE PARTITION p5 INTO (
    ->     PARTITION p3 VALUES LESS THAN (2005),
    ->     PARTITION p4 VALUES LESS THAN (2010)
    -> );
Query OK, 1826 rows affected (0.04 sec)
Records: 1826  Duplicates: 0  Warnings: 0

select
  partition_name part,
  partition_expression expr,
  partition_description descr,
  table_rows
from information_schema.partitions  where
  table_schema = schema()
  and table_name='trb3';
+------+------------------+-------+------------+
| part | expr             | descr | table_rows |
+------+------------------+-------+------------+
| p0   |  YEAR(purchased) | 1990  |       1826 |
| p1   |  YEAR(purchased) | 1995  |       1826 |
| p2   |  YEAR(purchased) | 2000  |       1826 |
| p3   |  YEAR(purchased) | 2005  |       1826 |
| p4   |  YEAR(purchased) | 2010  |          0 |
+------+------------------+-------+------------+
5 rows in set (0.00 sec)

HASH KEY分区

CREATE TABLE trb3 (id INT, name VARCHAR(50), purchased DATE)
    PARTITION BY hash( YEAR(purchased) )
    partitions 12;

mysql>call pr_trb3('1985-01-01','2004-12-31','trb3');

select
  partition_name part,
  partition_expression expr,
  partition_description descr,
  table_rows
from information_schema.partitions  where
  table_schema = schema()
  and table_name='trb3';
+------+------------------+-------+------------+
| part | expr             | descr | table_rows |
+------+------------------+-------+------------+
| p0   |  YEAR(purchased) | NULL  |        731 |
| p1   |  YEAR(purchased) | NULL  |        365 |
| p2   |  YEAR(purchased) | NULL  |        365 |
| p3   |  YEAR(purchased) | NULL  |        365 |
| p4   |  YEAR(purchased) | NULL  |        366 |
| p5   |  YEAR(purchased) | NULL  |        730 |
| p6   |  YEAR(purchased) | NULL  |        730 |
| p7   |  YEAR(purchased) | NULL  |        730 |
| p8   |  YEAR(purchased) | NULL  |        732 |
| p9   |  YEAR(purchased) | NULL  |        730 |
| p10  |  YEAR(purchased) | NULL  |        730 |
| p11  |  YEAR(purchased) | NULL  |        730 |
+------+------------------+-------+------------+
12 rows in set (0.00 sec)

缩建分区从12个到8个

mysql> ALTER TABLE trb3 COALESCE PARTITION 4;
Query OK, 7304 rows affected (0.13 sec)
Records: 7304  Duplicates: 0  Warnings: 0

select
  partition_name part,
  partition_expression expr,
  partition_description descr,
  table_rows
from information_schema.partitions  where
  table_schema = schema()
  and table_name='trb3';
+------+------------------+-------+------------+
| part | expr             | descr | table_rows |
+------+------------------+-------+------------+
| p0   |  YEAR(purchased) | NULL  |        732 |
| p1   |  YEAR(purchased) | NULL  |       1095 |
| p2   |  YEAR(purchased) | NULL  |       1095 |
| p3   |  YEAR(purchased) | NULL  |       1095 |
| p4   |  YEAR(purchased) | NULL  |       1097 |
| p5   |  YEAR(purchased) | NULL  |        730 |
| p6   |  YEAR(purchased) | NULL  |        730 |
| p7   |  YEAR(purchased) | NULL  |        730 |
+------+------------------+-------+------------+
8 rows in set (0.00 sec)

mysql> select count(*) from trb3;
+----------+
| count(*) |
+----------+
|     7304 |
+----------+
1 row in set (0.00 sec)

没丢数据

收缩前2004年在P0

mysql> select mod(2004,12);
+--------------+
| mod(2004,12) |
+--------------+
|            0 |
+--------------+

收缩后2004年在P4

mysql> select mod(2004,8);
+-------------+
| mod(2004,8) |
+-------------+
|           4 |
+-------------+

Exchanging Partitions and Subpartitions with Tables

分区(子分区)交换

 ALTER TABLE pt EXCHANGE PARTITION p WITH TABLE nt

pt是一个分区表,p是pt的分区或子分区,而nt是一个非分区表

限制条件:

1.表nt不是分区表
2.表nt不是临时表
3.表pt和nt结构在其他方面是相同的
4.表n没有外键约束,也没有其他表引用它的列为外键
5.表nt的所有行都包含在表p的分区范围内(比如p range分区最大values less than 10,那么表nt不能有大于等于10的值)

权限:

除了 ALTER, INSERT, and CREATE 权限外,你还要有DROP权限才能执行ALTER TABLE … EXCHANGE PARTITION.

其他注意事项:

1.执行ALTER TABLE … EXCHANGE PARTITION 不会调用任何在nt表和p表上的触发器
2.在交换表中的任何AUTO_INCREMENT列会被reset
3.IGNORE关键字在执行ALTER TABLE … EXCHANGE PARTITION时会失效

完整实例语句如下:

ALTER TABLE pt
    EXCHANGE PARTITION p
    WITH TABLE nt;

在一次ALTER TABLE EXCHANGE PARTITION 中,只能有一个分区和一个非分区表被交换
想交换多个,就执行多次ALTER TABLE EXCHANGE PARTITION
任何MySQL支持的分区类型都可以进行交换

交换实例

CREATE TABLE e (
    id INT NOT NULL,
    fname VARCHAR(30),
    lname VARCHAR(30)
)
    PARTITION BY RANGE (id) (
        PARTITION p0 VALUES LESS THAN (50),
        PARTITION p1 VALUES LESS THAN (100),
        PARTITION p2 VALUES LESS THAN (150),
        PARTITION p3 VALUES LESS THAN (MAXVALUE)
);

INSERT INTO e VALUES
    (1669, "Jim", "Smith"),
    (337, "Mary", "Jones"),
    (16, "Frank", "White"),
    (2005, "Linda", "Black");

创建一个与e结构一样的非分区表e2

mysql> create table e2 like e;
Query OK, 0 rows affected (0.01 sec)

mysql> show create table e2\G
*************************** 1. row ***************************
       Table: e2
Create Table: CREATE TABLE `e2` (
  `id` int(11) NOT NULL,
  `fname` varchar(30) DEFAULT NULL,
  `lname` varchar(30) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
/*!50100 PARTITION BY RANGE (id)
(PARTITION p0 VALUES LESS THAN (50) ENGINE = InnoDB,
 PARTITION p1 VALUES LESS THAN (100) ENGINE = InnoDB,
 PARTITION p2 VALUES LESS THAN (150) ENGINE = InnoDB,
 PARTITION p3 VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */
1 row in set (0.00 sec)

mysql> alter table e2 remove partitioning;
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> show create table e2\G
*************************** 1. row ***************************
       Table: e2
Create Table: CREATE TABLE `e2` (
  `id` int(11) NOT NULL,
  `fname` varchar(30) DEFAULT NULL,
  `lname` varchar(30) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

查看数据在e表中的分布:

select
  partition_name part,
  partition_expression expr,
  partition_description descr,
  table_rows
from information_schema.partitions  where
  table_schema = schema()
  and table_name='e'
+------+------+----------+------------+
| part | expr | descr    | table_rows |
+------+------+----------+------------+
| p0   | id   | 50       |          1 |
| p1   | id   | 100      |          0 |
| p2   | id   | 150      |          0 |
| p3   | id   | MAXVALUE |          3 |
+------+------+----------+------------+
4 rows in set (0.00 sec)

将分区p0与e2表进行交换:

mysql> ALTER TABLE e EXCHANGE PARTITION p0 WITH TABLE e2;
Query OK, 0 rows affected (0.01 sec)

select
  partition_name part,
  partition_expression expr,
  partition_description descr,
  table_rows
from information_schema.partitions  where
  table_schema = schema()
  and table_name='e';
+------+------+----------+------------+
| part | expr | descr    | table_rows |
+------+------+----------+------------+
| p0   | id   | 50       |          0 |
| p1   | id   | 100      |          0 |
| p2   | id   | 150      |          0 |
| p3   | id   | MAXVALUE |          3 |
+------+------+----------+------------+
4 rows in set (0.01 sec)

mysql> select * from e2;
+----+-------+-------+
| id | fname | lname |
+----+-------+-------+
| 16 | Frank | White |
+----+-------+-------+
1 row in set (0.00 sec)  

重做实验,这次在交换前在表e2中插入一些数据

mysql> insert into e2 values(16,'FAN','BOSHI');
Query OK, 1 row affected (0.00 sec)

mysql> insert into e2 values(51,'DU','YALAN');
Query OK, 1 row affected (0.00 sec)

mysql> select * from e2;
+----+-------+-------+
| id | fname | lname |
+----+-------+-------+
| 16 | FAN   | BOSHI |
| 51 | DU    | YALAN |
+----+-------+-------+
2 rows in set (0.00 sec)

mysql> ALTER TABLE e EXCHANGE PARTITION p0 WITH TABLE e2;
ERROR 1737 (HY000): Found a row that does not match the partition

报错了,因为51超出了p0的范围。
如之前所说,此时使用IGNORE也无济于事

mysql> ALTER IGNORE TABLE e EXCHANGE PARTITION p0 WITH TABLE e2;
ERROR 1737 (HY000): Found a row that does not match the partition

修改id为49,这样就属于p0的范围了

mysql> update e2 set id=49 where id=51;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> ALTER TABLE e EXCHANGE PARTITION p0 WITH TABLE e2;
Query OK, 0 rows affected (0.01 sec)

mysql> select
    ->   partition_name part,
    ->   partition_expression expr,
    ->   partition_description descr,
    ->   table_rows
    -> from information_schema.partitions  where
    ->   table_schema = schema()
    ->   and table_name='e';
+------+------+----------+------------+
| part | expr | descr    | table_rows |
+------+------+----------+------------+
| p0   | id   | 50       |          2 |
| p1   | id   | 100      |          0 |
| p2   | id   | 150      |          0 |
| p3   | id   | MAXVALUE |          3 |
+------+------+----------+------------+
4 rows in set (0.00 sec)

e2的数据被交换到了p0中
mysql> select * from e partition(p0);
+----+-------+-------+
| id | fname | lname |
+----+-------+-------+
| 16 | FAN   | BOSHI |
| 49 | DU    | YALAN |
+----+-------+-------+
2 rows in set (0.00 sec)

e的p0分区中的数据被交换到了e2中
mysql> select * from e2;
+----+-------+-------+
| id | fname | lname |
+----+-------+-------+
| 16 | Frank | White |
+----+-------+-------+
1 row in set (0.01 sec)

交换subpartition

CREATE TABLE es (
    id INT NOT NULL,
    fname VARCHAR(30),
    lname VARCHAR(30)
)
    PARTITION BY RANGE (id)
    SUBPARTITION BY KEY (lname)
    SUBPARTITIONS 2 (
        PARTITION p0 VALUES LESS THAN (50),
        PARTITION p1 VALUES LESS THAN (100),
        PARTITION p2 VALUES LESS THAN (150),
        PARTITION p3 VALUES LESS THAN (MAXVALUE)
    );

INSERT INTO es VALUES
    (1669, "Jim", "Smith"),
    (337, "Mary", "Jones"),
    (16, "Frank", "White"),
    (2005, "Linda", "Black");

CREATE TABLE es2 LIKE es;

ALTER TABLE es2 REMOVE PARTITIONING;

尽管我们没有显示的指定每个子分区的名字,我们仍可以通过information_schema.partitions表获取到子分区的名字

select
  partition_name part,
  subpartition_name,
  partition_expression expr,
  partition_description descr,
  table_rows
from information_schema.partitions  where
  table_schema = schema()
  and table_name='es';
+------+-------------------+------+----------+------------+
| part | subpartition_name | expr | descr    | table_rows |
+------+-------------------+------+----------+------------+
| p0   | p0sp0             | id   | 50       |          1 |
| p0   | p0sp1             | id   | 50       |          0 |
| p1   | p1sp0             | id   | 100      |          0 |
| p1   | p1sp1             | id   | 100      |          0 |
| p2   | p2sp0             | id   | 150      |          0 |
| p2   | p2sp1             | id   | 150      |          0 |
| p3   | p3sp0             | id   | MAXVALUE |          3 |
| p3   | p3sp1             | id   | MAXVALUE |          0 |
+------+-------------------+------+----------+------------+

接下来,开始将p3sp0和es进行交换

mysql> select * from es partition(p3sp0);
+------+-------+-------+
| id   | fname | lname |
+------+-------+-------+
| 1669 | Jim   | Smith |
|  337 | Mary  | Jones |
| 2005 | Linda | Black |
+------+-------+-------+
3 rows in set (0.00 sec)

mysql> ALTER TABLE es EXCHANGE PARTITION p3sp0 WITH TABLE es2;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from es partition(p3sp0);
Empty set (0.00 sec)

mysql> select * from es2;
+------+-------+-------+
| id   | fname | lname |
+------+-------+-------+
| 1669 | Jim   | Smith |
|  337 | Mary  | Jones |
| 2005 | Linda | Black |
+------+-------+-------+
3 rows in set (0.00 sec)

如果一个分区表有子分区,那么你只能以子分区为粒度进行交换,而不能直接交换子分区的父分区

mysql> ALTER TABLE es EXCHANGE PARTITION p3 WITH TABLE es2;
ERROR 1704 (HY000): Subpartitioned table, use subpartition instead of partition

EXCHANGE PARTITION有着严格的要求
两个将要交换的表的 列名,列的创建顺序,列的数量,以及索引都要严格一致。当然存储引擎也要一致

mysql> desc es2;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int(11)     | NO   |     | NULL    |       |
| fname | varchar(30) | YES  |     | NULL    |       |
| lname | varchar(30) | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

mysql> create index id_name on es2(id,fname);
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> ALTER TABLE es EXCHANGE PARTITION p3sp0 WITH TABLE es2;
ERROR 1736 (HY000): Tables have different definitions

改变es2的存储引擎

mysql> drop index id_name on es2;
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> alter table es2 engine=myisam;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> ALTER TABLE es EXCHANGE PARTITION p3sp0 WITH TABLE es2;
ERROR 1497 (HY000): The mix of handlers in the partitions is not allowed in this version of MySQL

分区表的维护

CHECK TABLE, OPTIMIZE TABLE, ANALYZE TABLE, and REPAIR TABLE可以被用于维护分区表

Rebuilding partitions.相当于将分区中的数据drop掉再插入回来,对于避免磁盘碎片很有效
Example:

ALTER TABLE t1 REBUILD PARTITION p0, p1;

Optimizing partitions.如果你的表增加删除了大量数据,或者进行了大量的边长列的更新操作( VARCHAR, BLOB, or TEXT columns)。那么optimize partition将回收未使用的空间,并整理分区数据文件。
Example:

ALTER TABLE t1 OPTIMIZE PARTITION p0, p1;

运行OPTIMIZE PARTITION 相当于做了 CHECK PARTITION, ANALYZE PARTITION, and REPAIR PARTITION

Some MySQL storage engines, including InnoDB, do not support per-partition optimization; in these cases, ALTER TABLE … OPTIMIZE PARTITION rebuilds the entire table. In MySQL 5.6.9 and later, running this statement on such a table causes the entire table to rebuilt and analyzed, and an appropriate warning to be issued. (Bug #11751825, Bug #42822) Use ALTER TABLE … REBUILD PARTITION and ALTER TABLE … ANALYZE PARTITION instead, to avoid this issue.

Analyzing partitions.读取并保存分区的键分布
Example:

ALTER TABLE t1 ANALYZE PARTITION p3;

Repairing partitions.修补被破坏的分区
Example:

ALTER TABLE t1 REPAIR PARTITION p0,p1;

Checking partitions.可以使用几乎与对非分区表使用CHECK TABLE 相同的方式检查分区。
Example:

ALTER TABLE trb3 CHECK PARTITION p1;

这个命令可以告诉你表trb3的分区p1中的数据或索引是否已经被破坏。如果发生了这种情况,使用“ALTER TABLE … REPAIR PARTITION”来修补该分区。

以上每个命令都支持将分区换成ALL

The use of mysqlcheck and myisamchk is not supported with partitioned tables.

mysqlcheck和myisamchk不支持分区表

你可以使用 ALTER TABLE … TRUNCATE PARTITION. 来删除一个或多个分区中的数据
如:ALTER TABLE … TRUNCATE PARTITION ALL删除所有数据

ANALYZE, CHECK, OPTIMIZE, REBUILD, REPAIR, and TRUNCATE 操作不支持 subpartitions.

Mysql --分区表的管理与维护的更多相关文章

  1. 数据切分——Mysql分区表的管理与维护

    关于Mysql分区表的介绍可以参考: http://blog.csdn.net/jhq0113/article/details/44592865 关于Mysql分区表的创建可以参考: http://b ...

  2. MySQL分区表的管理~2

    一.维护分区 对于表的维护,我们一般有如下几种方式: CHECK TABLE, OPTIMIZE TABLE, ANALYZE TABLE和REPAIR TABLE. 而这几种方式,对于分区同样适用. ...

  3. MySQL分区表的管理~1

    一.如何管理RANGE和LIST分区 以该分区表为例 CREATE TABLE members ( id INT, fname ), lname ), dob DATE ) PARTITION BY ...

  4. MySQL复制的管理和维护

    1.查看主库 mysql> show master status; mysql> show master status; +------------------+-----------+- ...

  5. MySQL 分区表

    转载自MySQL 分区表 今天统计数据的时候发现一张表使用了表分区,借此机会记录一下. 1. 什么是表分区? 表分区,是指根据一定规则,将数据库中的一张表分解成多个更小的,容易管理的部分.从逻辑上看, ...

  6. MySQL 分区表原理及数据备份转移实战

    MySQL 分区表原理及数据备份转移实战 1.分区表含义 分区表定义指根据可以设置为任意大小的规则,跨文件系统分配单个表的多个部分.实际上,表的不同部分在不同的位置被存储为单独的表.用户所选择的.实现 ...

  7. 详解MySQL分区表

    当数据库数据量涨到一定数量时,性能就成为我们不能不关注的问题,如何优化呢? 常用的方式不外乎那么几种: 1.分表,即把一个很大的表达数据分到几个表中,这样每个表数据都不多. 优点:提高并发量,减小锁的 ...

  8. MySQL 分区表,为什么分区键必须是主键的一部分?

    随着业务的不断发展,数据库中的数据会越来越多,相应地,单表的数据量也会越到越大,大到一个临界值,单表的查询性能就会下降. 这个临界值,并不能一概而论,它与硬件能力.具体业务有关. 虽然在很多 MySQ ...

  9. 常用MySQL图形化管理工具

    MySQL的管理维护工具非常多,除了系统自带的命令行管理工具之外,还有许多其他的图形化管理工具,这里我介绍几个经常使用的MySQL图形化管理工具,供大家参考. MySQL是一个非常流行的小型关系型数据 ...

随机推荐

  1. avi文件打开出现花屏、打开不了问题

    以avi为后缀名文件,其编码格式并不是单一的,而是多种格式都可以以avi作为后缀. AVI(Audio Video Interleaved的缩写)是一种RIFF(Resource Interchang ...

  2. WebBrowser打开Word文档的一些注意事项

    WebBrowser打开Word文档的一些注意事项 分类: C#word2010-03-31 21:26 5640人阅读 评论(3) 收藏 举报 webbrowser文档browser工具object ...

  3. Direct2D相关

    1,如何绘制文本 2,文本格式设置和布局

  4. I/O流——其他流

    其他流 一.ObjectInputStream/ObjectOutputStream ① ObjectInputStream和ObjectOutputStream分别与FileInputStream和 ...

  5. Android剪贴板操作----ClipboardManager

    andrid developers java.lang.Object ---android.text.ClipboardManager ------android.context.ClipboardM ...

  6. Unity3D中制作Loading场景进度条

    背景 通常游戏的主场景包含的资源较多,这会导致加载场景的时间较长.为了避免这个问题,可以首先加载Loading场景,然后再通过Loading场景来加载主场景.由于Loading场景包含的资源较少,所以 ...

  7. selenium第一课(selenium+java+testNG+maven)

    selenium介绍和环境搭建 一.简单介绍 1.selenium:Selenium是一个用于Web应用程序测试的工具.Selenium测试直接运行在浏览器中,就像真正的用户在操作一样.支持的浏览器包 ...

  8. 数据库事务中的隔离级别和锁+spring Transactional注解

    数据库事务中的隔离级别和锁 数据库事务在后端开发中占非常重要的地位,如何确保数据读取的正确性.安全性也是我们需要研究的问题.ACID首先总结一下数据库事务正确执行的四个要素(ACID): 原子性(At ...

  9. 《VB语言程序设计(第3版)》总结

    我之前因学习昆仑通态的组态软件MCGS,用并学习过VB,还买了一本书<VB语言程序设计(第3版)>.现在在某公司实习,最近接触老的项目,又要用到VB.我就又把那本书大体看了一遍,并对其进行 ...

  10. Xamarin踩坑经历

    1.SDK版本 Android SDK Build-tools必须安装23.0.1版,不得升级高版本,否则将导致异常:尝试在条件"$(_DeviceSdkVersion) >= 21& ...