当前位置:网站首页>MySQL 分区表介绍与测试
MySQL 分区表介绍与测试
2022-06-12 12:21:00 【Thai_】
一、基本介绍:
分区表是一个独立的逻辑表,底层由多个物理的文件组成,分区对于 SQL 层来说是透明的;
下图可以看出,表 em_elec_meter_data 的多个分区是使用了 # 进行标识。

分区表的使用场景:
- 表非常大以至于无法全部都放在内存中,或者热点数据只有在表的最后部分,其他都是历史数据。
- 分区表的数据作用在不同的设备上,高效地利用多个硬件设备;例如有 1TB 的数据,服务器的硬盘容量只有 500 GB,那么可以使用其他设备平摊未能放下的数据。
- 需要独立备份和恢复分区,这在非常大数据集的场景下效果非常好。
分区表的限制:
- 一个表最多只能有 1024 个分区。
- MySQL 5.1 中,分区表表达式必须是整数,或者返回整数表达式。在 MySQL 5.5 中,某些场景中可以直接使用列来进行分区。
- 如果分区字段中有主键或者唯一索引的列,那么所有主键列和唯一索引列都必须组合成一个主键;原因是防止同一个主键一个在 p0 区,一个在 p1 区。
- 分区表中无法使用外键约束(现在也没人使用外键,都是程序保证约束)。
- 在 MySQL 8 中不支持 myIsam 存储引擎使用分区表。
分区表的类型:
范围(range)分区,例如某年某月、不同省份的区域范围(常用)
注:每个分区都是按顺序进行定义,从最低到最高,例如以下的 2023 不能在 2022 的前面,这是 PARTITION BY RANGE 语法的要求
# 按照范围分区的表 create table `range_partition1` ( `id` bigint not null auto_increment, `date_time` datetime not null, `range_name` varchar(50) default null, primary key (`id`, `date_time`) ) ENGINE = InnoDB default CHARSET = utf8mb4 collate = utf8mb4_0900_ai_ci partition by range(year(date_time)) ( -- 必须按照顺序定义,否则报错 partition p0 values less than (2022), partition p1 values less than (2023) )哈希(hash)分区,将数据均匀的分布到预先定义的各个分区中,使用
partition by hash(expr)指定为 hash 分区,需要注意expr必须返回整数或者指定的列为 MySQL 的整型。CREATE TABLE `hash_partition` ( `id` bigint NOT NULL AUTO_INCREMENT, `date_time` datetime NOT NULL, `range_name` varchar(50) DEFAULT NULL, PRIMARY KEY (`id`,`date_time`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci partition by hash(id) partitions 10;partitions 10的意思为表要被切分成 10 个分区
键值(key)分区,KEY分区和HASH分区相似,不同之处在于 HASH 分区使用用户定义的函数进行分区,KEY 分区使用数据库提供的函数进行分区。
CREATE TABLE `key_partition` ( `id` bigint NOT NULL AUTO_INCREMENT, `date_time` datetime NOT NULL, `range_name` varchar(50) DEFAULT NULL, PRIMARY KEY (`id`,`date_time`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci partition by linear key(id) partitions 10;列表(list)分区,根据给定的 list 进行分区;以下例子为按照月份进行春夏秋冬四季的分区
CREATE TABLE `list_partition` ( `id` bigint NOT NULL AUTO_INCREMENT, `date_time` datetime NOT NULL, `range_name` varchar(50) DEFAULT NULL, PRIMARY KEY (`id`,`date_time`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci partition by list(month(date_time)) ( partition spring values in (3, 4, 5), partition summer values in (6, 7, 8), partition autumn values in (9, 10, 11), partition winter values in (12, 1, 2) )
二、分区表的优缺点
优点:
- 提升查询性能,对于分区表的查询操作,如果查询条件中包含分区键,则这个查询操作就只会被下推到符合条件的分区内进行,无关分区将自动过滤掉。
- 对业务透明,将表从一个非分区表转换为分区表,业务端无需做任何改造。在开发看来,仍然是同一张表。
- 维护方便,在对单个分区进行删除、迁移和维护时,不会影响到其它分区。
- DML 操作加锁仅影响操作的分区,不会影响未访问分区。
缺点:
- DDL 操作需要锁定所有分区,导致所有分区上操作都被阻塞。
- 当表数据量较小时,分区表和非分区表性能相近,分区表效果有限。
- 当表数据量较大时,对分区表进行 DDL 或其他运维操作难度大风险高。
- 分区表使用较少,存在未知风险多,BUG多,BUG多,BUG多,MySQL社区版本免费,横向扩展成本低,分库分表实现简单且中间件完善。
- 当单台服务器性能无法满足时,对分区表进行分拆的成本较高,而分库分表能很容易实现横向分拆。
- 当分区表操作不当导致访问所有分区时,会导致严重的性能问题,而分库分表操作不当仅影响访问的表。
- 使用分库分表可以有效运维降低运维操作影响,对1亿数据量表做 DDL 操作需要谨慎评估,而对 10 万数据量表做 DDL 操作可以默认其很快完成。
- 使用分库分表可以有效减小宕机或其他故障影响,将数据分库分表到10套群集上,一套群集发生故障仅影响业务的一成。
三、测试:
新建表 em_elec_meter_data,按月份从 2019 年到 2023 年对表进行分区划分。
CREATE TABLE `em_elec_meter_data` (
`id` bigint NOT NULL COMMENT '表主键',
`date_time` datetime NOT NULL COMMENT '时间。',
`create_time` datetime DEFAULT NULL COMMENT '改记录生成的时间',
PRIMARY KEY (`id`,`date_time`),
UNIQUE KEY `IDX_MIDDATE` (`meter_id`,`date_time`),
KEY `IDX_DATETIME` (`date_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT=''
/*!50100 PARTITION BY RANGE (to_days(`date_time`)) (PARTITION md201901 VALUES LESS THAN (737456) ENGINE = InnoDB, 略..... PARTITION md202312 VALUES LESS THAN (739251) ENGINE = InnoDB) */
向表插入数据, em_elec_meter_data 有大概 7 千万条数据,下面演示使用分区与不使用分区的差别

首先看不使用分区,执行以下 SQL,实测耗时 1 min 7 s
select
sql_no_cache /* 为了更真实,不使用缓存 */
*
from
test.em_elec_meter_data
where
dya = 10086

查看它的执行计划,需要查找所有的分区,大概扫描 66184007 行记录才找到 dya = 10086 这条记录

添加分区字段过滤,执行以下 SQL,实测耗时 1ms,性能提高约 67000 倍
select
sql_no_cache /* 为了更真实,不使用缓存 */
*
from
test.em_elec_meter_data
where
dya = 10086
and date_time = '2019-01-01 13:56:59';

再看看执行计划,只需查找 md201901 这个分区,且用到了 date_time索引

参考:
高性能 MySQL
https://www.cnblogs.com/gaogao67/p/11013244.html?ivk_sa=1024320u
边栏推荐
- Reprint --win10 open the task manager to solve the blue screen problem
- What can LDAP and SSO integration achieve?
- Take the web page animation effects that can be used. Don't you come and have a look?
- Promise knowledge
- JS attribute operation and node operation
- LDAP和SSO集成能实现什么效果?
- bind、call、apply三者的区别,还有bind()的封装
- 从小白入手,从已经训练好的模型中取出weight权重参数绘制柱状图
- 无重复字符的最长字符串(LeetCode 3)
- MVC mode, encryption, jsonwebtoken
猜你喜欢

Take the web page animation effects that can be used. Don't you come and have a look?

安装canvas遇到的问题和运行项目遇到的报错

Point cloud registration -- GICP principle and its application in PCL

LeetCode 497. Random points in non overlapping rectangles (prefix and + bisection)

DOM+JS+轮播图+无时间
![[JS] some handwriting functions: deep copy, bind, debounce, etc](/img/f8/cf51a24450a88abb9e68c78e0e3aa8.jpg)
[JS] some handwriting functions: deep copy, bind, debounce, etc

Matlab install license manager error -8

Longest string without duplicate characters (leetcode 3)

Bat interview & advanced, get interview materials at the end of the text

Lightweight ---project
随机推荐
NDT配准原理
左右案例+小圆点的轮播图+无时间
Left and right cases + rotating pictures of small dots + no time
Start with Xiaobai, take the weight parameter from the trained model and draw the histogram
Dom+js+ carousel map + no time
从小白入手,从已经训练好的模型中取出weight权重参数绘制柱状图
BAT面试&高级进阶,文末领取面试资料
Decision tree of machine learning
In navigation, the solution of adding borders to affect the layout
Invalid date of moment conversion timestamp
Implementation principle of kotlin extension function
Pre order, middle order and post order traversal of tree
[transfer]placement NEW
Boot entry directory
win7注册进程外组件, 服务, 以及COM组件调试
MVC模式、加密、jsonwebtoken
TRON-api-波场转账查询接口-PHP版本-基于ThinkPHP5封装-附带接口文档-20220528版本
【Leetcode】637. Layer average of binary tree
sublime_ Textuse
What is modularity? Benefits of modularity