MySQL分區管理


以下是我看MySQL官方文檔的時候整理的筆記,僅作參考保留。
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
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

 最后歡迎加入技術交流群:291519319

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM