mysql分区语句

1:为未分区表创建分区

ALTER TABLE trb3 PARTITION BY KEY(id) PARTITIONS 2;

2:删除某个分区的数据

ALTER TABLE tr DROP PARTITION p2;

3:为分区表添加一个分区

复制代码

ALTER TABLE members ADD PARTITION (PARTITION p3 VALUES LESS THAN (2000));
ALTER TABLE tt ADD PARTITION (PARTITION p2 VALUES IN (7, 14, 21));
ALTER TABLE employees ADD PARTITION (
    PARTITION p5 VALUES LESS THAN (2010),
    PARTITION p6 VALUES LESS THAN MAXVALUE
);

复制代码

4:将分区表的第一个分区分为两个新的分区

ALTER TABLE members
    REORGANIZE PARTITION p0 INTO (
        PARTITION n0 VALUES LESS THAN (1960),
        PARTITION n1 VALUES LESS THAN (1970)
);

5:也可以将两个分区合并为一个分区,也可以理解为重新组织分区

复制代码

ALTER TABLE members REORGANIZE PARTITION s0,s1 INTO (
    PARTITION p0 VALUES LESS THAN (1970)
);
ALTER TABLE tbl_name
    REORGANIZE PARTITION partition_list
    INTO (partition_definitions);
ALTER TABLE members REORGANIZE PARTITION p0,p1,p2,p3 INTO (
    PARTITION m0 VALUES LESS THAN (1980),
    PARTITION m1 VALUES LESS THAN (2000)
);
ALTER TABLE tt ADD PARTITION (PARTITION np VALUES IN (4, 8));
ALTER TABLE tt REORGANIZE PARTITION p1,np INTO (
    PARTITION p1 VALUES IN (6, 18),
    PARTITION np VALUES in (4, 8, 12)
);

复制代码

HASH,KEY 分区管理

1:创建一个hash分区表

复制代码

CREATE TABLE clients (
    id INT,
    fname VARCHAR(30),
    lname VARCHAR(30),
    signed DATE
)
PARTITION BY HASH( MONTH(signed) )
PARTITIONS 12;

复制代码

将分区表从12个分区变为8个分区

ALTER TABLE clients COALESCE PARTITION 4;

同样的有以下的语句关于KEY分区的表:

复制代码

mysql> CREATE TABLE clients_lk (
    ->     id INT,
    ->     fname VARCHAR(30),
    ->     lname VARCHAR(30),
    ->     signed DATE
    -> )
    -> PARTITION BY LINEAR KEY(signed)
    -> PARTITIONS 12;
Query OK, 0 rows affected (0.03 sec)

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

复制代码

当然还有有限制的

mysql> ALTER TABLE clients COALESCE PARTITION 18;
ERROR 1478 (HY000): Cannot remove all partitions, use DROP TABLE instead

要是分区数比现有的分区数多的话,只能使用 ADD来添加分区数.下面就表示增加了6个分区数

ALTER TABLE clients ADD PARTITION PARTITIONS 6;

交换分区,子分区的管理

交换分区,ALTER TABLE pt EXCHANGE PARTITION p WITH TABLE nt

where pt is the partitioned table and p is the partition or subpartition of pt to be exchanged with unpartitioned table nt, provided that the following statements are true:

要满足以下的条件:

1:PT是已经分区表,nt不是临时表

2:两张表的表结构必须是一模一样的

3:nt不能有外键约束,也不能有关于其他表的外键约束.

4:nt表中的数据没有分区P以外的数据.WITHOUT VALIDATION指定的时候这条就可以忽视调

另外很重要的一点就是想要拥有EXCHANGE的权限的话必须对全表有DROP的权限才可以执行.

 

alter table  ......EXCHANGE partition  将不会调用任何的触发器,执行完以后被EXCHANGE 的表的自增列就会重新赋初始值.

例如:

ALTER TABLE pt 
    EXCHANGE PARTITION p 
    WITH TABLE nt with VALIDATION ;

1:将分区和一个没有分区的表EXCHANGE

 

创建表插入语句:

复制代码

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");

复制代码

查看分区和分区的行数

 

复制代码

 SELECT PARTITION_NAME, TABLE_ROWS 
    FROM INFORMATION_SCHEMA.PARTITIONS 
    WHERE TABLE_NAME = 'e';
 
SELECT TABLE_NAME, PARTITION_NAME, TABLE_ROWS, AVG_ROW_LENGTH, DATA_LENGTH FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_SCHEMA = 'p' AND TABLE_NAME LIKE 'e';

复制代码

创建新表:

CREATE TABLE e2 LIKE e;

然后交换分区开始了:

ALTER TABLE e EXCHANGE PARTITION p0 WITH TABLE e2;

这个语句是很奇怪的,如果e2里面没有数据的话就是切出分区,如果e2里面有数据的话就是相互交换

但是如果e2里面的数据不能够满足分区p0的要求的话,切分区就会失败.

1737 - Found a row that does not match the partition

只有再指定不验证的时候才不会报错

ALTER TABLE e EXCHANGE PARTITION p0 WITH TABLE e2 WITHOUT VALIDATION;

WITHOUT VALIDATION 指定的时候效率会更高,因为不再做逐行验证了.

 

 

子分区和没分区的表进行切换

 

1:假设创建一个分区表,带有子分区

复制代码

> 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)
    ->     );

复制代码

然后就可以切分区了,先查看一下分区,

SELECT PARTITION_NAME, SUBPARTITION_NAME, TABLE_ROWS
     FROM INFORMATION_SCHEMA.PARTITIONS
     WHERE TABLE_NAME = 'es';

然后切出分区:

ALTER TABLE es EXCHANGE PARTITION p3sp0 WITH TABLE es2;

当前执行切出分区前,必须要对新表做以下的处理:

ALTER TABLE es2 REMOVE PARTITIONING;

修改表的默认引擎:

ALTER TABLE es3 ENGINE = MyISAM;

维护表分区

1:重建分区

ALTER TABLE t1 REBUILD PARTITION p0, p1;

2:重新组织分区

ALTER TABLE t1 OPTIMIZE PARTITION p0, p1;

3:分析某个分区,主要看行数和名称以及状态

ALTER TABLE t1 ANALYZE PARTITION p3;

4:修复分区,有重复值的时候就会报错.

ALTER TABLE t1 REPAIR PARTITION p0,p1;

5:检查分区的状态

ALTER TABLE trb3 CHECK PARTITION p1;

6:truncate分区 

ALTER TABLE ... TRUNCATE PARTITION.
ALTER TABLE ... TRUNCATE PARTITION ALL 

7:获取表的信息

Using the SHOW CREATE TABLE statement to view the partitioning clauses used in creating a partitioned table.

Using the SHOW TABLE STATUS statement to determine whether a table is partitioned.

Querying the INFORMATION_SCHEMA.PARTITIONS table.

Using the statement EXPLAIN PARTITIONS SELECT to see which partitions are used by a given SELECT.

看以下信息:

复制代码

mysql> EXPLAIN PARTITIONS SELECT * FROM trb1\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: trb1
   partitions: p0,p1,p2,p3
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 10
        Extra: Using filesort

复制代码

分区的经典案例:

复制代码

mysql> CREATE TABLE employees_sub  (
    ->     id INT NOT NULL AUTO_INCREMENT,
    ->     fname VARCHAR(25) NOT NULL,
    ->     lname VARCHAR(25) NOT NULL,
    ->     store_id INT NOT NULL,
    ->     department_id INT NOT NULL,
    ->     PRIMARY KEY pk (id, lname)
    -> )   
    ->     PARTITION BY RANGE(id)
    ->     SUBPARTITION BY KEY (lname)
    ->     SUBPARTITIONS 2 (
    ->         PARTITION p0 VALUES LESS THAN (5),
    ->         PARTITION p1 VALUES LESS THAN (10),
    ->         PARTITION p2 VALUES LESS THAN (15),
    ->         PARTITION p3 VALUES LESS THAN MAXVALUE
    -> );

复制代码

分区的一些添删查修语句:

复制代码

mysql> DELETE FROM employees PARTITION (p0, p1) 
    ->     WHERE fname LIKE 'j%';
Query OK, 2 rows affected (0.09 sec)
mysql> UPDATE employees PARTITION (p2)
    ->     SET store_id = 2 WHERE fname = 'Jill';
SELECT * FROM employees PARTITION (p2);
mysql> INSERT INTO employees PARTITION (p2) VALUES (20, 'Jan', 'Jones', 1, 3);ERROR 1729 (HY000): Found a row not matching the given partition set
mysql> INSERT INTO employees PARTITION (p3) VALUES (20, 'Jan', 'Jones', 1, 3);
Query OK, 1 row affected (0.07 sec)

复制代码

分区不够多,要添加分区:

复制代码

ysql> ALTER TABLE employees
    ->     REORGANIZE PARTITION p3 INTO (
    ->         PARTITION p3 VALUES LESS THAN (20),
    ->         PARTITION p4 VALUES LESS THAN (25),
    ->         PARTITION p5 VALUES LESS THAN MAXVALUE
    ->     );
Query OK, 6 rows affected (2.09 sec)
Records: 6  Duplicates: 0  Warnings: 0

复制代码

RANGE,LIST分区管理

1:为未分区表创建分区

ALTER TABLE trb3 PARTITION BY KEY(id) PARTITIONS 2;

2:删除某个分区的数据

ALTER TABLE tr DROP PARTITION p2;

3:为分区表添加一个分区

复制代码

ALTER TABLE members ADD PARTITION (PARTITION p3 VALUES LESS THAN (2000));
ALTER TABLE tt ADD PARTITION (PARTITION p2 VALUES IN (7, 14, 21));
ALTER TABLE employees ADD PARTITION (
    PARTITION p5 VALUES LESS THAN (2010),
    PARTITION p6 VALUES LESS THAN MAXVALUE
);

复制代码

4:将分区表的第一个分区分为两个新的分区

ALTER TABLE members
    REORGANIZE PARTITION p0 INTO (
        PARTITION n0 VALUES LESS THAN (1960),
        PARTITION n1 VALUES LESS THAN (1970)
);

5:也可以将两个分区合并为一个分区,也可以理解为重新组织分区

复制代码

ALTER TABLE members REORGANIZE PARTITION s0,s1 INTO (
    PARTITION p0 VALUES LESS THAN (1970)
);
ALTER TABLE tbl_name
    REORGANIZE PARTITION partition_list
    INTO (partition_definitions);
ALTER TABLE members REORGANIZE PARTITION p0,p1,p2,p3 INTO (
    PARTITION m0 VALUES LESS THAN (1980),
    PARTITION m1 VALUES LESS THAN (2000)
);
ALTER TABLE tt ADD PARTITION (PARTITION np VALUES IN (4, 8));
ALTER TABLE tt REORGANIZE PARTITION p1,np INTO (
    PARTITION p1 VALUES IN (6, 18),
    PARTITION np VALUES in (4, 8, 12)
);

复制代码

HASH,KEY 分区管理

1:创建一个hash分区表

复制代码

CREATE TABLE clients (
    id INT,
    fname VARCHAR(30),
    lname VARCHAR(30),
    signed DATE
)
PARTITION BY HASH( MONTH(signed) )
PARTITIONS 12;

复制代码

将分区表从12个分区变为8个分区

ALTER TABLE clients COALESCE PARTITION 4;

同样的有以下的语句关于KEY分区的表:

复制代码

mysql> CREATE TABLE clients_lk (
    ->     id INT,
    ->     fname VARCHAR(30),
    ->     lname VARCHAR(30),
    ->     signed DATE
    -> )
    -> PARTITION BY LINEAR KEY(signed)
    -> PARTITIONS 12;
Query OK, 0 rows affected (0.03 sec)

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

复制代码

当然还有有限制的

mysql> ALTER TABLE clients COALESCE PARTITION 18;
ERROR 1478 (HY000): Cannot remove all partitions, use DROP TABLE instead

要是分区数比现有的分区数多的话,只能使用 ADD来添加分区数.下面就表示增加了6个分区数

ALTER TABLE clients ADD PARTITION PARTITIONS 6;

交换分区,子分区的管理

交换分区,

ALTER TABLE pt EXCHANGE PARTITION p WITH TABLE nt

where pt is the partitioned table and p is the partition or subpartition of pt to be exchanged with unpartitioned table nt, provided that the following statements are true:

要满足以下的条件:

1:PT是已经分区表,nt不是临时表

2:两张表的表结构必须是一模一样的

3:nt不能有外键约束,也不能有关于其他表的外键约束.

4:nt表中的数据没有分区P以外的数据.WITHOUT VALIDATION指定的时候这条就可以忽视调

另外很重要的一点就是想要拥有EXCHANGE的权限的话必须对全表有DROP的权限才可以执行.

 

alter table  ......EXCHANGE partition  将不会调用任何的触发器,执行完以后被EXCHANGE 的表的自增列就会重新赋初始值.

例如:

ALTER TABLE pt 
    EXCHANGE PARTITION p 
    WITH TABLE nt with VALIDATION ;

1:将分区和一个没有分区的表EXCHANGE

 

创建表插入语句:

复制代码

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");

复制代码

查看分区和分区的行数 

 SELECT PARTITION_NAME, TABLE_ROWS 
    FROM INFORMATION_SCHEMA.PARTITIONS 
    WHERE TABLE_NAME = 'e';
SELECT TABLE_NAME, PARTITION_NAME, TABLE_ROWS, AVG_ROW_LENGTH, DATA_LENGTH FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_SCHEMA = 'p' AND TABLE_NAME LIKE 'e';

 

创建新表:

CREATE TABLE e2 LIKE e;

然后交换分区开始了:

ALTER TABLE e EXCHANGE PARTITION p0 WITH TABLE e2;

这个语句是很奇怪的,如果e2里面没有数据的话就是切出分区,如果e2里面有数据的话就是相互交换

但是如果e2里面的数据不能够满足分区p0的要求的话,切分区就会失败.

1737 - Found a row that does not match the partition

只有再指定不验证的时候才不会报错

ALTER TABLE e EXCHANGE PARTITION p0 WITH TABLE e2 WITHOUT VALIDATION;

WITHOUT VALIDATION 指定的时候效率会更高,因为不再做逐行验证了.

 

 

子分区和没分区的表进行切换

 

1:假设创建一个分区表,带有子分区

复制代码

> 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)
    ->     );

复制代码

然后就可以切分区了,先查看一下分区,

SELECT PARTITION_NAME, SUBPARTITION_NAME, TABLE_ROWS
     FROM INFORMATION_SCHEMA.PARTITIONS
     WHERE TABLE_NAME = 'es';

然后切出分区:

ALTER TABLE es EXCHANGE PARTITION p3sp0 WITH TABLE es2;

当前执行切出分区前,必须要对新表做以下的处理:

ALTER TABLE es2 REMOVE PARTITIONING;

修改表的默认引擎:

ALTER TABLE es3 ENGINE = MyISAM;

维护表分区

1:重建分区

ALTER TABLE t1 REBUILD PARTITION p0, p1;

2:重新组织分区

ALTER TABLE t1 OPTIMIZE PARTITION p0, p1;

3:分析某个分区,主要看行数和名称以及状态

ALTER TABLE t1 ANALYZE PARTITION p3;

4:修复分区,有重复值的时候就会报错.

ALTER TABLE t1 REPAIR PARTITION p0,p1;

5:检查分区的状态

ALTER TABLE trb3 CHECK PARTITION p1;

6:truncate分区

 

ALTER TABLE ... TRUNCATE PARTITION.
ALTER TABLE ... TRUNCATE PARTITION ALL 

 

7:获取表的信息

Using the SHOW CREATE TABLE statement to view the partitioning clauses used in creating a partitioned table.

Using the SHOW TABLE STATUS statement to determine whether a table is partitioned.

Querying the INFORMATION_SCHEMA.PARTITIONS table.

Using the statement EXPLAIN PARTITIONS SELECT to see which partitions are used by a given SELECT.

看以下信息:

复制代码

mysql> EXPLAIN PARTITIONS SELECT * FROM trb1\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: trb1
   partitions: p0,p1,p2,p3
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 10
        Extra: Using filesort

复制代码

 

 

 

 

分区的经典案例:

复制代码

mysql> CREATE TABLE employees_sub  (
    ->     id INT NOT NULL AUTO_INCREMENT,
    ->     fname VARCHAR(25) NOT NULL,
    ->     lname VARCHAR(25) NOT NULL,
    ->     store_id INT NOT NULL,
    ->     department_id INT NOT NULL,
    ->     PRIMARY KEY pk (id, lname)
    -> )   
    ->     PARTITION BY RANGE(id)
    ->     SUBPARTITION BY KEY (lname)
    ->     SUBPARTITIONS 2 (
    ->         PARTITION p0 VALUES LESS THAN (5),
    ->         PARTITION p1 VALUES LESS THAN (10),
    ->         PARTITION p2 VALUES LESS THAN (15),
    ->         PARTITION p3 VALUES LESS THAN MAXVALUE
    -> );

复制代码

分区的一些添删查修语句:

复制代码

mysql> DELETE FROM employees PARTITION (p0, p1) 
    ->     WHERE fname LIKE 'j%';
Query OK, 2 rows affected (0.09 sec)
mysql> UPDATE employees PARTITION (p2)
    ->     SET store_id = 2 WHERE fname = 'Jill';
SELECT * FROM employees PARTITION (p2);
mysql> INSERT INTO employees PARTITION (p2) VALUES (20, 'Jan', 'Jones', 1, 3);ERROR 1729 (HY000): Found a row not matching the given partition set
mysql> INSERT INTO employees PARTITION (p3) VALUES (20, 'Jan', 'Jones', 1, 3);
Query OK, 1 row affected (0.07 sec)

复制代码

分区不够多,要添加分区:

复制代码

ysql> ALTER TABLE employees
    ->     REORGANIZE PARTITION p3 INTO (
    ->         PARTITION p3 VALUES LESS THAN (20),
    ->         PARTITION p4 VALUES LESS THAN (25),
    ->         PARTITION p5 VALUES LESS THAN MAXVALUE
    ->     );
Query OK, 6 rows affected (2.09 sec)
Records: 6  Duplicates: 0  Warnings: 0
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
这样可以提高查询的性能。创建多字段索引可以通过以下两种方式实现: 1. 创建复合索引:复合索引是指在多个字段上创建的索引。可以使用CREATE INDEX语句MySQL提供了分区来创建复合索引。例如,下面的语句创建了一个复合索引,包含两个字段(field1和field2): ``` CREATE INDEX index_name ON table_name (表的功能,可以将大表field1, field2); ```拆分成多个小表,提高查询性能和管理效率。在建表时,可以使用以下语法来创建分区表: CREATE TABLE table_name ( column1 data 这样创建的索引将按照field1和field2的顺序进行排序,并且可以在查询中使用这两个字段进行搜索。 2._type, column2 data_type, ... ) PARTITION BY partitioning_method ( PARTITION partition_name VALUES LESS THAN (value), PARTITION partition_name VALUES LESS THAN (value 创建前缀索引:前缀索引是指只对字段的一部分进行索引。可以使用CREATE INDEX语句来创建前缀索引,), ... ); 其中,table_name是要创建的分区表的名称,column1、column2等是表的列名和数据类型。partitioning_method是分区方法,可以选择以下几种: 1. RANGE分区:按照指定的范并指定字段的前缀长度。例如,下面的语句创建了一个前缀索引,只对字段field1的前10个字符进行索引: ``` CREATE INDEX index_name ON table_name (field1(10)); ```围对数据进行分区。例如,可以按照日期范围或者数值范围进行分区。 2. LIST分区:按照指定的值列表对数据进行分区。 这样创建的索引只会对字段的前10个字符进行排序,并且可以在查询中使用这个字段的前缀进行搜索。 需要注意的是,例如,可以按照地区或者部门进行分区。 3. HASH分区:根据列值的哈希值进行分区。例如,可以根据用户ID的哈希值进行分创建多字段索引可能会增加索引的大小和维护成本。因此,在创建多字段索引时,需要根据实际情况权衡性能和资源消耗。区。 4. KEY分区:类似于HASH分区,但是是根据列值的键值进行分区。 在PARTITION子句中, 可以使用VALUES LESS THAN来指定每个分区的取值范围。例如,VALUES LESS THAN (value)表示该分区存储小于value的数据。 以下是一个示例的分区表创建语句: CREATE TABLE sales ( id INT, sale_date DATE, amount DECIMAL(10,2) ) PARTITION BY RANGE (YEAR(sale_date)) ( PARTITION p0 VALUES LESS THAN (2010), PARTITION p1 VALUES LESS THAN (2015), PARTITION p2 VALUES LESS THAN (2020), PARTITION p3 VALUES LESS THAN MAXVALUE ); 上述语句创建了一个名为sales的分区表,按照sale_date列的年份进行分区。其中,p0存储2010年之前的数据,p1存储2010年到2014年的数据,p2存储2015年到2019年的数据,p3存储2020年及以后的数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值