MySQL 表分区和事件调度器
Contents
MySQL 表分区
MySQL表分区是将一个大表分割成若干个小表的技术。这样做可以提高查询和维护的效率,并且还可以改善数据的管理方式。
注意:如果分区字段中有主键或者唯一索引的列,那么所有主键列和唯一索引列都必须包含进来(即分区的字段也必须是主键或者唯一索引)
分区适用场景
- 大型表处理
- 时间范围查询
- 数据归档和数据保留
- 并行查询和负载均衡
- 数据删除和维护
判断当前MySQL是否支持分区?
|
|
以下是几种常见的分区类型:
-
RANGE分区:基于给定的一个给定列的值,将数据划分到不同的分区。
-
LIST分区:类似于RANGE分区,但是列值是离散的集合。
-
HASH分区:基于用户定义的表达式的返回值进行分区,该表达式对分区的数量进行哈希。
-
KEY分区:类似于HASH分区,但是使用的哈希函数是由MySQL服务器提供的。
-
COLUMNS分区:基于列值的范围或列表来进行分区,适用于某些特定的数据类型。
RANGE分区
以下是一个RANGE分区的示例:
假设有一个orders表,包含一个order_date字段,可以根据order_date字段的值将表分为几个分区:
|
|
创建了一个按年份划分的orders表,将订单按照它们的年份放入不同的分区。p0分区包含order_date在2023年以前的所有订单,p1分区包含2024年,以此类推。pmax分区包含所有2026年以后的订单。
LIST分区
LIST 分区是根据某一列的离散值将数据分布到不同的分区。
示例:
|
|
HASH分区
HASH 分区是使用哈希算法将数据均匀地分布到多个分区中。
示例:
|
|
PARTITIONS 4 指定4个分区
KEY分区
KEY 分区是根据某一列的哈希值将数据分布到不同的分区。和HASH分区不同在于使用的哈希算法不同。
示例:
|
|
PARTITIONS 4 指定4个分区
COLUMNS 分区
包括 RANGE COLUMNS 分区和 LIST COLUMNS 分区
RANGE COLUMNS 分区是根据列的范围值将数据分布到不同的分区的分区策略。
|
|
LIST COLUMNS 分区是根据列的离散值将数据分布到不同的分区的分区策略。
|
|
添加分区
|
|
删除分区
|
|
drop方式删除会删除分区数据
|
|
remove不会删除数据
重新分区
range分区
|
|
hash分区
|
|
合并分区
合并相邻两个分区
|
|
合并两个分区
|
|
重组分区
|
|
查询分区分析
|
|
分区统计信息
|
|
表分区操作实践
方便学习,直接在 Docker 中运行 MySQL 容器。
拉取MySQL镜像
|
|
运行 MySQL 容器
|
|
-
--name mysql-partition-test
:为当前的容器指定运行中的一个名称,这里命名为 mysql-partition-test。 -
-e MYSQL_ROOT_PASSWORD=a123456
:设置 root 用户的密码。这里设置为a123456。 -
-d:在后台运行容器。
-
mysql:8.0.35:指定要使用的 MySQL 镜像的标签tag=8.0.35版本
如果想要自定义配置或挂载本地数据卷,可以添加如下启动配置项
-
-v /my/own/datadir:/var/lib/mysql
挂载数据卷,持久化存储数据,挂载一个卷到容器的 /var/lib/mysql 目录 -
-v /my/custom/conf:/etc/mysql/conf.d
可以通过挂载一个包含自定义 my.cnf 的卷来覆盖默认的 MySQL 配置
查看容器运行结果
|
|
访问 MySQL 容器,并连接数据库
|
|
连接和操作数据库
|
|
创建一个订单表
|
|
查看数据库表
|
|
创建分区表
以订单表为例,用创建时间created_at
按范围分区(RANGE),
如果按年分区直接使用 RANGE(YEAR(created_at))
按月分区RANGE(YEAR(created_at)*100+MONTH(created_at))
按天分区RANGE(TO_DAYS(created_at))
下面是按月分区:
|
|
执行创建时失败,提示分区键选择不正确,原因是分区键必须是主键和唯一索引的一部分,否则就无法确定数据存储在哪个分区。
|
|
MySQL要求:
-
分区表达式中使用的所有列必须是表可能使用的每个唯一键的一部分
-
这意味着如果表有主键或唯一索引,这些键必须包含分区列
修改索引如下,主键和唯一索引添加created_at
字段:
|
|
注意事项:
- 查询性能:尽可能在查询条件中包含分区键(created_at)以实现分区裁剪
写入数据
|
|
查询分区数据
|
|
复合分区
|
|
先按id分3个RANGE分区,每个RANGE分区中两个KEY(order_no)
子分区
自动维护分区
对于动态数据,可能需要定期添加新的分区来覆盖新月份的数据。
可以写一个脚本或使用事件调度器(Event Scheduler)来自动添加新的分区。
例如,使用事件调度器每月自动添加下个月新分区的步骤如下:
|
|
- 查看事件调度器的状态
|
|
- 开启事件调度器
|
|
- 创建和测试事件
|
|
这个事件每2秒执行一次insert写入一条数据,执行后事件自动开始运行。
- 查看所有event
|
|
- 事件开启和关闭
|
|
- 删除事件
|
|