1. 概述
官方文档:https://dev.mysql.com/doc/refman/5.7/en/partitioning-overview.html
通过删除仅包含该数据的分区(或多个分区),通常可以轻松地从分区表中删除失去其实用性的数据。相反,在某些情况下,通过添加一个或多个新分区来特别存储该数据,可以极大地促进添加新数据的过程。
由于满足给定WHERE子句的数据只能存储在一个或多个分区上,因此可以大大优化某些查询,这会自动从搜索中排除任何剩余的分区。由于在创建分区表后可以更改分区,因此可以重新组织数据以增强在首次设置分区方案时可能不常使用的频繁查询。这种排除不匹配分区(以及它们包含的任何行)的能力通常称为 分区修剪。
查看是否支持分区
1 | MariaDB []> SHOW PLUGINS; |
Name | Status | Type |
---|---|---|
partition | ACTIVEt | STORAGE ENGINE |
2.完成一个空的分区表创建
2.1 Create Table:
1 | CREATE TABLE `test1` ( |
2.2 创建表后, 数据库目录下会生成3个分区的表空间
1 | [root@localhost ~]# ls /var/lib/mysql/test -lh |
插入测试数据:
1 | INSERT INTO test1(sip,insertTime) VALUES ('1.1.1.4','2019-03-27 01:00:03'); #p0 |
2.3 分区查询
1 | mysql 5.6之后才引入分区查询 |
查看分区
1
MariaDB [test]> SELECT TABLE_SCHEMA, TABLE_NAME, PARTITION_NAME, PARTITION_EXPRESSION, PARTITION_DESCRIPTION FROM INFORMATION_SCHEMA.partitions WHERE TABLE_NAME LIKE 'cdr' AND TABLE_SCHEMA LIKE SCHEMA();
查看分区数目
1
MariaDB [test]> SELECT count(PARTITION_NAME) FROM INFORMATION_SCHEMA.partitions WHERE TABLE_NAME LIKE 'cdr' AND TABLE_SCHEMA LIKE SCHEMA();
根据创建的分区范围界定来查询数据, 确定是对应哪个分区
1
MariaDB [test]> explain partitions SELECT * FROM test1 WHERE insertTime="2019-03-30 01:00:03";
id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | Extra |
---|---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | test1 | p1 | ALL | NULL | NULL | NULL | NULL | 2 | Using where |
1 | MariaDB [test]> explain partitions SELECT * FROM test1 WHERE insertTime="2019-03-27 01:00:03"; |
id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | Extra |
---|---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | test1 | p0 | ALL | NULL | NULL | NULL | NULL | 2 | Using where |
1 | MariaDB [test]> explain partitions SELECT * FROM test1 WHERE insertTime="2019-03-31 01:00:03"; |
id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | Extra |
---|---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | test1 | p2 | ALL | NULL | NULL | NULL | NULL | 2 | Using where |
2.4 查看分区字段的信息
查看最小插入和最大插入时间
1
select min(insertTime),max(insertTime) from test1;
查看每天插入数据的条数
1
select date(insertTime),count(*) from test group by date(insertTime);
2.5 删除分区
命令行删除
1
2MariaDB [test]> alter table test1 drop partition p0;
`数据库下对应的分区会消失
1
2
3
4
5
6[root@localhost ~]# ls /var/lib/mysql/test -lh
总用量 41M
-rw-rw----. 1 mysql mysql 14K 3月 29 11:41 test1.frm
-rw-rw----. 1 mysql mysql 40 3月 29 11:41 test1.par
-rw-rw----. 1 mysql mysql 96K 3月 29 11:40 test1#P#p1.ibd
-rw-rw----. 1 mysql mysql 96K 3月 29 11:40 test1#P#p2.ibd分区中涵盖的数据也会消失
1
SELECT count(*) FROM test1;
3. 对已经存在的数据表进行range分区
3.1 备份表, 只有插入数据
1 | mysqldump --no-create-info testdb tb1 > cdrtest.sql |
3.2 删除表
1 | DROP TABLE tb1; |
3.3 创建表, 要根据已经创建表格式, 将需要分区的字段作为主键或复合主键
查看原表创建语句
1
SHOW CREATE TABLE tb1;
修改原来的语句, 生成新的语句
1
2
3
4
5
6CREATE TABLE `tb1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`sip` varchar(32) NOT NULL,
`insertTime` timestamp NOT NULL,
PRIMARY KEY (`id`,`insertTime`)
) ENGINE=InnoDB;
3.4 表不存在分区, 将主键字段作为范围去分区, timestamp类型只能使用UNIX_TIMESTAMP函数
1 | ALTER TABLE tb1 PARTITION by range(UNIX_TIMESTAMP(insertTime))( |
3.5 添加分区, 已经存在分区了
1 | ALTER TABLE cdr add partition (partition par3 values less than (UNIX_TIMESTAMP('2019-04-01 00:00:00'))); |
3.6 删除分区, 上面已经有命令
4. 对已经存在的数据表进行list分区
4.1 创建表, 要根据已经创建表格式, 将需要分区的字段作为主键或复合主键
查看原表创建语句
1
SHOW CREATE TABLE tb1;
修改原来的语句, 生成新的语句
1
2
3
4
5
6CREATE TABLE `tb1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`sip` varchar(32) NOT NULL,
`insertTime` timestamp NOT NULL,
PRIMARY KEY (`id`,`response_code`)
) ENGINE=InnoDB;
4.2 表不存在分区, 对一个字段可以存在的范围去定义分区. 而且只能插入满足的定义分区的数据
1 | ALTER TABLE cdr PARTITION BY list(response_code) |
5. 脚本小结
1 |
|