MySQL创建管理RANGE分区


Posted in MySQL onApril 13, 2022

介绍

RANGE分区基于一个给定的连续区间范围,早期版本RANGE主要是基于整数的分区。在5.7版本中DATE、DATETIME列也可以使用RANGE分区,同时在5.5以上的版本提供了基于非整形的RANGE COLUMN分区。RANGE分区必须的连续的且不能重叠。使用

“VALUES LESS THAN ()”来定义分区区间,非整形的范围值需要使用单引号,并且可以使用MAXVALUE作为分区的最高值。

一、RANGE分区

1.创建分区

CREATE TABLE employees (
    id INT NOT NULL,
    fname VARCHAR(30),
    lname VARCHAR(30),
    hired DATE NOT NULL DEFAULT '1970-01-01',
    separated DATE NOT NULL DEFAULT '9999-12-31',
    job_code INT NOT NULL,
    store_id INT NOT NULL
)
PARTITION BY RANGE (store_id) (
    PARTITION p0 VALUES LESS THAN (6),
    PARTITION p1 VALUES LESS THAN (11),
    PARTITION p2 VALUES LESS THAN (16),
    PARTITION p3 VALUES LESS THAN (21)
);
alter table employees add index ix_store_id(store_id) ;alter table employees add index ix_job_code(job_code) ;

p0:指分区p0,这个分区名的取值可以随便取值只要同一个表里面的每个分区名不重复即可,也不需要非得从0开始,你也可以使用a、b、c、d。

THEN():分区的范围值,这个值只能的连续不重叠的从小到大的值。

2.性能分析

插入测试数据

insert into employees(id,job_code,store_id) values(1,1001,1),(2,1002,2),(3,1003,3),(4,1004,4);

MySQL创建管理RANGE分区

从执行计划可以看到两个查询都用到了分区的效果;如果细心估计会发现第二个查询没有走索引,并不是使用小于就不会走索引而且执行计划分析评估任务不走索引的效果会更好,事实却是如果当前查询整个分区的数据时使用索引的话还需要去查询其它的字段还不如直接扫描整个分区来的快。

3.增加分区

由于当前分区值的范围是小于21,当向分区表中插入一个超过分区范围的值时会报错。这个时候可以增加一个分区,当你不确定需要给一个多大的上限值时可以使用MAXVALUE

MySQL创建管理RANGE分区

alter table employees add PARTITION  (PARTITION p4 VALUES LESS THAN MAXVALUE);

注意:增加分区只能在最大端增加

4.删除分区

alter table employees drop  PARTITION p4;

注意:通过这种删除分区的方式会将分区中的数据也删除,慎用!!!!。但是通过删除分区的方式删除数据会比delete快很多,因为它相当于删除一个数据库一样因为每个分区都是一个独立的数据文件。用来删除历史分区数据是非常好的办法。

5.拆分合并分区

拆分合并分区统称为重新定义分区,拆分分为不会造成数据的丢失,只将会将数据从一个分区移动到另一个分区。

例1:将P0拆分成s1,s2两个分区

ALTER TABLE employees REORGANIZE PARTITION p0 INTO (
    PARTITION s0 VALUES LESS THAN (3),
    PARTITION s1 VALUES LESS THAN (6)
);

注意:原来分区p0的范围是[负无穷-6),所以新拆分的分区也必须是这范围,所以新的分区范围值最大不能超过6。

MySQL创建管理RANGE分区

分区由原来的p0[-6)变成了so[-3),s1[3-6),整个分区的范围还是不变。

例2:将s1,p1,p2合并为a,b两个分区

ALTER TABLE employees REORGANIZE PARTITION s1,p1,p2 INTO (
    PARTITION a VALUES LESS THAN (5),
    PARTITION b VALUES LESS THAN (16)
);

原本的s1,p1,p2分区范围是:[3-16)所以新的分区也必须和原本的分区相同,所以新的分区的值不能低于3不能高于16即可。

MySQL创建管理RANGE分区

分区由原来的s1[3-6),p1[6-11),p2[11-16)变成了现在的a[3-5),b[5-16),总的范围没有发生变化

注意:无论是拆分还是合并分区都不能改变分区原本的覆盖范围,并且合并分区只能合并连续的分区不能跳过分区合并;并且不能改变分区的类型,例如不能把range分区改成key分区等。

二、日期字段分区方法

注意:RANG分区针对日期字段进行分区可以使用时间类型的函数进行转换成整形,但是如果你的查询语句需要利用分区那么查询语句也需要使用相同的时间函数进行查询。

1.使用YEAR()函数进行分区

CREATE TABLE employees1 (
    id INT NOT NULL,
    fname VARCHAR(30),
    lname VARCHAR(30),
    hired DATE NOT NULL DEFAULT '1970-01-01',
    separated DATE NOT NULL DEFAULT '9999-12-31',
    job_code INT,
    store_id INT
)
PARTITION BY RANGE ( YEAR(separated) ) (
    PARTITION p0 VALUES LESS THAN (1991),
    PARTITION p1 VALUES LESS THAN (1996),
    PARTITION p2 VALUES LESS THAN (2001),
    PARTITION p3 VALUES LESS THAN MAXVALUE
);

插入测试数据

insert into employees1(id,separated,job_code,store_id) values(1,'1990-03-04',1001,1),(2,'1995-03-04',1002,2),(3,'1998-03-04',1003,3),(4,'2016-03-04',1004,4);

MySQL创建管理RANGE分区

对于日期字段分区,查询条件使用> 、< 、betnwen、=都会利用分区查询,如果条件使用函数转换则不会走分区,比如使用YEAR()。

2.TIMESTAMP类型的列的分区方法

针对TIMESTAMP的日期类型的字段需要使用专门的UNIX_TIMESTAMP()函数进行转换

CREATE TABLE quarterly_report_status (
    report_id INT NOT NULL,
    report_status VARCHAR(20) NOT NULL,
    report_updated TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
)
PARTITION BY RANGE ( UNIX_TIMESTAMP(report_updated) ) (
    PARTITION p0 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-01-01 00:00:00') ),
    PARTITION p1 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-04-01 00:00:00') ),
    PARTITION p2 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-07-01 00:00:00') ),
    PARTITION p3 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-10-01 00:00:00') ),
    PARTITION p4 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-01-01 00:00:00') ),
    PARTITION p5 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-04-01 00:00:00') ),
    PARTITION p6 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-07-01 00:00:00') ),
    PARTITION p7 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-10-01 00:00:00') ),
    PARTITION p8 VALUES LESS THAN ( UNIX_TIMESTAMP('2010-01-01 00:00:00') ),
    PARTITION p9 VALUES LESS THAN (MAXVALUE)
);

三、null值处理

当往分区列中插入null值RANG 分区会将其当作最小值来处理即插入最小的分区中

CREATE TABLE test (
    id INT NOT NULL,
    store_id INT 
)
PARTITION BY RANGE (store_id) (
    PARTITION p0 VALUES LESS THAN (6),
    PARTITION p1 VALUES LESS THAN (11),
    PARTITION p2 VALUES LESS THAN (16),
    PARTITION p3 VALUES LESS THAN (21)
);
insert into test(id,store_id) values(1,null);
SELECT PARTITION_NAME,PARTITION_METHOD,PARTITION_EXPRESSION,PARTITION_DESCRIPTION,TABLE_ROWS,SUBPARTITION_NAME,SUBPARTITION_METHOD,SUBPARTITION_EXPRESSION 
FROM information_schema.PARTITIONS WHERE TABLE_SCHEMA=SCHEMA() AND TABLE_NAME='test';

MySQL创建管理RANGE分区

备注:文章中的示例摘自mysql官方参考手册

四、移除表的分区

ALTER TABLE tablename
REMOVE PARTITIONING ;

注意:使用remove移除分区是仅仅移除分区的定义,并不会删除数据和drop PARTITION不一样,后者会连同数据一起删除

总结

有两点非常重要需要注意,第一删除分区时要慎重因为会连同分区里的数据一并删除,拆分合并分区新的分区一定要和原来的分区的范围一致。RANGE COLUMN分区单独用章节进行讲解,。

到此这篇关于MySQL分区之RANGE分区的文章就介绍到这了!

MySQL 相关文章推荐
解决MySQL存储时间出现不一致的问题
Apr 28 MySQL
解读MySQL的客户端和服务端协议
May 10 MySQL
Mysql文件存储图文详解
Jun 01 MySQL
浅析MySQL如何实现事务隔离
Jun 26 MySQL
mysql 数据插入优化方法之concurrent_insert
Jul 01 MySQL
MySQL系列之三 基础篇
Jul 02 MySQL
SQL IDENTITY_INSERT作用案例详解
Aug 23 MySQL
mysql下的max_allowed_packet参数设置详解
Feb 12 MySQL
MySQL中B树索引和B+树索引的区别详解
Mar 03 MySQL
Pycharm远程调试和MySQL数据库授权问题
Mar 18 MySQL
MySQL创建管理LIST分区
Apr 13 MySQL
MySQL数据库如何查看表占用空间大小
Jun 10 MySQL
MySQL创建管理LIST分区
Apr 13 #MySQL
MySql分区类型及创建分区的方法
Apr 13 #MySQL
深入理解mysql事务隔离级别和存储引擎
mysql使用 not int 子查询隐含陷阱
Apr 12 #MySQL
MySQL数据库如何使用Shell进行连接
CentOS 7安装mysql5.7使用XtraBackUp备份工具命令详解
Apr 12 #MySQL
MySQL事务操作的四大特性以及并发事务问题
You might like
2019十大人气国漫
2020/03/13 国漫
Thinkphp的volist标签嵌套循环使用教程
2014/07/08 PHP
[原创]php求圆周率的简单实现方法
2016/05/30 PHP
php和js实现根据子网掩码和ip计算子网功能示例
2019/11/09 PHP
JQUERY实现左侧TIPS滑进滑出效果示例
2013/06/27 Javascript
Backbone.js 0.9.2 源码注释中文翻译版
2015/06/25 Javascript
jquery 遍历数组 each 方法详解
2016/05/25 Javascript
JavaScript实现星星等级评价功能
2017/03/22 Javascript
详解如何让Express支持async/await
2017/10/09 Javascript
薪资那么高的Web前端必看书单
2017/10/13 Javascript
vue-prop父组件向子组件进行传值的方法
2018/03/01 Javascript
Koa2微信公众号开发之本地开发调试环境搭建
2018/05/16 Javascript
详解vue的diff算法原理
2018/05/20 Javascript
解决vue 中 echart 在子组件中只显示一次的问题
2018/08/07 Javascript
从零撸一个pc端vue的ui组件库( 计数器组件 )
2019/08/08 Javascript
Vue中qs插件的使用详解
2020/02/07 Javascript
layui实现显示数据表格、搜索和修改功能示例
2020/06/03 Javascript
寻找网站后台地址的python脚本
2014/09/01 Python
简介Django中内置的一些中间件
2015/07/24 Python
带你了解python装饰器
2017/06/15 Python
Python实现基本数据结构中栈的操作示例
2017/12/04 Python
对Python3中的print函数以及与python2的对比分析
2018/05/02 Python
Django 构建模板form表单的两种方法
2020/06/14 Python
Python如何绘制日历图和热力图
2020/08/07 Python
基于python模拟TCP3次握手连接及发送数据
2020/11/06 Python
C语言中break与continue的区别
2012/07/12 面试题
工商管理专业实习大学生自我鉴定
2013/09/19 职场文书
大学生专科学习生活的自我评价
2013/12/07 职场文书
高校优秀辅导员事迹材料
2014/05/07 职场文书
2014年挂职干部工作总结
2014/12/06 职场文书
2015小学毕业班工作总结
2015/07/21 职场文书
大学生安全教育主题班会
2015/08/12 职场文书
详解Python牛顿插值法
2021/05/11 Python
5分钟教你docker安装启动redis全教程(全新方式)
2021/05/29 Redis
springboot 全局异常处理和统一响应对象的处理方式
2022/06/28 Java/Android
Nginx如何配置多个服务域名解析共用80端口详解
2022/09/23 Servers