MySQL 表分区(十)
• 对分区表可以通过 ALTER TABLE pt EXCHANGE PARTITION p WITH TABLE nt 命令将一个分区或者是子分区的数据与普通的表的数据相互交换,其本身的表结构不会变化
• 交换的分区表和目标表必须结构完全相同,包括字段,类型,索引,存储引擎必须完全一样
mysql> select * from tr; +------+------+------------+ | id | name | purchased | +------+------+------------+ | 2 | abc | 1999-12-21 | | 1 | abc | 1999-12-21 | +------+------+------------+ 2 rows in set (0.00 sec) mysql> select * from tr_history; +------+------+------------+ | id | name | purchased | +------+------+------------+ | 1 | a | 2000-01-01 | +------+------+------------+ 1 row in set (0.00 sec) mysql> select * from tr partition(p3); +------+------+------------+ | id | name | purchased | +------+------+------------+ | 2 | abc | 1999-12-21 | | 1 | abc | 1999-12-21 | +------+------+------------+ 2 rows in set (0.00 sec) mysql> desc tr; +-----------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-----------+-------------+------+-----+---------+-------+ | id | int(11) | YES | | NULL | | | name | varchar(50) | YES | | NULL | | | purchased | date | YES | | NULL | | +-----------+-------------+------+-----+---------+-------+ 3 rows in set (0.00 sec) mysql> desc tr_history; +-----------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-----------+-------------+------+-----+---------+-------+ | id | int(11) | YES | | NULL | | | name | varchar(50) | YES | | NULL | | | purchased | date | YES | | NULL | | +-----------+-------------+------+-----+---------+-------+ 3 rows in set (0.00 sec) mysql> alter table tr_history modify name varchar(100); Query OK, 1 row affected (0.28 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> alter table tr EXCHANGE PARTITION p3 WITH TABLE tr_history; ERROR 1736 (HY000): Tables have different definitions mysql> alter table tr_history modify name varchar(50); Query OK, 1 row affected (0.26 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> show create table tr_history; +------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Table | Create Table | +------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | tr_history | CREATE TABLE `tr_history` ( `id` int(11) DEFAULT NULL, `name` varchar(50) DEFAULT NULL, `purchased` date DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci | +------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec) mysql> create index idx_1 on tr_history(id); Query OK, 0 rows affected (0.19 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> alter table tr EXCHANGE PARTITION p3 WITH TABLE tr_history; ERROR 1736 (HY000): Tables have different definitions
• 执行 exchange 命令时,目标表里不一定是空数据,如果有数据需要保证里面的数据符合表分区的条件,否则只能用 WITHOUT VALIDATION 来跳过验证环节
mysql> select * from tr_history; +------+------+------------+ | id | name | purchased | +------+------+------------+ | 1 | a | 2000-01-01 | +------+------+------------+ 1 row in set (0.00 sec) mysql> show create table tr; +-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Table | Create Table | +-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | tr | CREATE TABLE `tr` ( `id` int(11) DEFAULT NULL, `name` varchar(50) DEFAULT NULL, `purchased` date DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci /*!50100 PARTITION BY RANGE (year(`purchased`)) (PARTITION p1 VALUES LESS THAN (1995) ENGINE = InnoDB, PARTITION p3 VALUES LESS THAN (2005) ENGINE = InnoDB, PARTITION p4 VALUES LESS THAN (2010) ENGINE = InnoDB, PARTITION p5 VALUES LESS THAN (2015) ENGINE = InnoDB) */ | +-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec) mysql> alter table tr EXCHANGE PARTITION p1 WITH TABLE tr_history; ERROR 1736 (HY000): Tables have different definitions mysql> drop index idx_1 on tr_history; Query OK, 0 rows affected (0.09 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> alter table tr EXCHANGE PARTITION p1 WITH TABLE tr_history; ERROR 1737 (HY000): Found a row that does not match the partition mysql> alter table tr EXCHANGE PARTITION p1 WITH TABLE tr_history WITHOUT VALIDATION; Query OK, 0 rows affected (0.31 sec) mysql> select * from tr partition(p1); +------+------+------------+ | id | name | purchased | +------+------+------------+ | 1 | a | 2000-01-01 | +------+------+------------+ 1 row in set (0.01 sec)
mysql> select * from tr; +------+------+------------+ | id | name | purchased | +------+------+------------+ | 1 | a | 2000-01-01 | | 2 | abc | 1999-12-21 | | 1 | abc | 1999-12-21 | +------+------+------------+ 3 rows in set (0.00 sec) mysql> show create table tr; +-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Table | Create Table | +-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | tr | CREATE TABLE `tr` ( `id` int(11) DEFAULT NULL, `name` varchar(50) DEFAULT NULL, `purchased` date DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci /*!50100 PARTITION BY RANGE (year(`purchased`)) (PARTITION p1 VALUES LESS THAN (1995) ENGINE = InnoDB, PARTITION p3 VALUES LESS THAN (2005) ENGINE = InnoDB, PARTITION p4 VALUES LESS THAN (2010) ENGINE = InnoDB, PARTITION p5 VALUES LESS THAN (2015) ENGINE = InnoDB) */ | +-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec) mysql> explain select * from tr wherepurchased='2010-01-01'; ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '='2010-01-01'' at line 1 mysql> explain select * from tr where purchased='2010-01-01'; +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+ | 1 | SIMPLE | tr | p5 | ALL | NULL | NULL | NULL | NULL | 1 | 100.00 | Using where | +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+ 1 row in set, 1 warning (0.00 sec) mysql> explain select * from tr; +----+-------------+-------+-------------+------+---------------+------+---------+------+------+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+-------------+------+---------------+------+---------+------+------+----------+-------+ | 1 | SIMPLE | tr | p1,p3,p4,p5 | ALL | NULL | NULL | NULL | NULL | 2 | 100.00 | NULL | +----+-------------+-------+-------------+------+---------------+------+---------+------+------+----------+-------+ 1 row in set, 1 warning (0.00 sec) mysql> explain select * from tr where name='a'; +----+-------------+-------+-------------+------+---------------+------+---------+------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+-------------+------+---------------+------+---------+------+------+----------+-------------+ | 1 | SIMPLE | tr | p1,p3,p4,p5 | ALL | NULL | NULL | NULL | NULL | 2 | 50.00 | Using where | +----+-------------+-------+-------------+------+---------------+------+---------+------+------+----------+-------------+ 1 row in set, 1 warning (0.00 sec)

浙公网安备 33010602011771号