MySQL分区详解
创始人
2024-03-27 14:10:45
0

目录

一、定义

1.1 概述

1.2 分区的优势

二、分区的类型

2.1 检查MySQL是否支持分区

2.2 类型

2.3 分区的其他操作


一、定义 

1.1 概述

数据库分区是一种物理数据库设计技术。虽然分区技术可以实现很多效果,但其主要目的是为了在特定的SQL操作中减少数据读写的总量以缩减SQL语句的响应时间,同时对于应用来说分区完全是透明的。

使用myisam引擎的一张表主要对应着三个文件,一个是frm存放表结构的,一个是myd存放表数据的,一个是myi存表索引的。如果一张表的数据量太大的话,那么myd、myi就会变的很大,查找数据就会变的很慢,这个时候我们可以利用mysql的分区功能,在物理上将这一张表对应的三个文件,分割成许多个小块,这样我们查找一条数据时,就不用全部查找了,只要知道这条数据在哪一块,然后在那一块找就行了。如果表的数据太大,可能一个磁盘放不下,我们可以把数据分配到不同的磁盘里面去。

使用innoDB引擎的/mysql/data/数据库名目录下一张表有一个frm文件存放数据结构,其他的数据部分全部都存在在/mysql/data目录下的ibdata文件中。

MYSQL 5.1之后支持分区。

1.2 分区的优势

1)与单个磁盘或文件系统分区相比,可以存储更多的数据。
2)对于不用或者过时的数据很容易给删除掉。
3)对于一些查询有极大的优化,给定WHERE语句的数据可以只保存在一个或多个分区内,这样就不需要查找剩余的数据。
4)涉及到例如SUM()和COUNT()这样聚合函数的查询,可以很容易地进行并行处理。
5)通过跨多个磁盘来分散数据查询,来获得更大的查询吞吐量。

二、分区的类型

2.1 检查MySQL是否支持分区

//查看mysql5.6以下是否支持分区
show variables like '%partition%';//查看mysql5.6以上是否支持分区
show plugins;

2.2 类型

使用分区的前提:分区键必须是主键的一部分。

解释:分区键必须是主键的一部分并不是 MySQL 的限制,而是索引组织表的限制。之所以对索引组织表有这样的限制,个人认为还是基于性能考虑。假设分区键和主键是两个不同的列,在进行插入操作时,虽然也指定了分区键,但还是需要扫描所有分区才能判断插入的主键值是否违反了唯一性约束。这样的话,效率会比较低下,违背了分区表的初衷。而对于堆表则没有这样的限制,下面是堆表和索引组织表的定义。

堆表:数据存储在表中,索引存储在索引里,两者分开的。数据在堆中是无序的,索引让键值有序,但数据还是无序的。堆表中主键索引和普通索引一样的,都是存放指向堆表中数据的指针。

索引组织表:数据存储在聚簇索引中,或者说,数据按照主键的顺序来组织数据,两者合二为一。主键索引,叶子节点存放整行数据。其他索引称为辅助索引(二级索引),叶子节点存放键值和主键值。

创建表和表数据 

CREATE TABLE `user_login_log` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT,`user_id` int(10) DEFAULT NULL,`login_time` int(10) unsigned DEFAULT '0',`ip` varchar(255) DEFAULT NULL,`add_time` int(10) unsigned DEFAULT '0',`up_time` int(10) unsigned DEFAULT '0',PRIMARY KEY (`id`,`user_id`,`login_time`),KEY `ip` (`ip`)
) ENGINE=InnoDB AUTO_INCREMENT=1000002 DEFAULT CHARSET=utf8 COMMENT='用户登录日志';

1)range分区
按照RANGE分区的表是通过如下一种方式进行分区的,每个分区包含那些分区表达式的值位于一个给定的连续区间内的行。

//添加字段 user_id(复合主键) 的range分区
ALTER table `user_login_log`  PARTITION BY RANGE (`user_id`) (PARTITION p0 VALUES LESS THAN (101000), PARTITION p1 VALUES LESS THAN (201000),PARTITION p2 VALUES LESS THAN (301000),PARTITION p3 VALUES LESS THAN (401000),PARTITION p4 VALUES LESS THAN (501000),PARTITION p5 VALUES LESS THAN (601000),PARTITION p6 VALUES LESS THAN (701000),PARTITION p7 VALUES LESS THAN (801000),PARTITION p8 VALUES LESS THAN (901000),PARTITION p9 VALUES LESS THAN MAXVALUE
);//查询语句,增加分区前查询耗时 0.976s,增加分区后查询耗时 0.293s,可看到有三倍的增速
select * from `user_login_log` where user_id>=50001 and user_id<=100000;

2)list分区
LIST分区中每个分区的定义和选择是基于某列的值从属于一个值列表集中的一个值,而RANGE分区是从属于一个连续区间值的集合。

//添加字段 login_time(复合主键) 的list分区
ALTER table `user_login_log`  PARTITION BY LIST COLUMNS(`login_time`) (PARTITION p0 VALUES in("2022-12-07 08:22:32", "2022-12-07 09:23:32", "2022-12-07 12:13:44"),PARTITION p1 VALUES in("2022-12-07 09:23:45", "2022-12-07 10:16:32", "2022-12-07 08:21:32"),PARTITION p2 VALUES in("2022-12-07 09:42:55", "2022-12-07 05:02:25", "2022-12-07 08:23:42"),PARTITION p3 VALUES in("2022-12-07 11:08:02", "2022-12-07 06:22:33")
);//查询语句,增加分区前查询耗时 1.187s,增加分区后查询耗时 0.717s,可看到有 0.47s的增速
select * from `user_login_log` where login_time in("2022-12-07 08:22:32", "2022-12-07 09:23:32", "2022-12-07 12:13:44");

3)hash分区
HASH分区主要用来确保数据在预先确定数目的分区中平均分布,你所要做的只是基于将要被哈希的列值指定一个列值或表达式,以 及指定被分区的表将要被分割成的分区数量。

//添加字段 user_id(复合主键) 的hash分区
ALTER table `user_login_log`  PARTITION BY HASH (`user_id`) PARTITIONS 10;//查询语句,增加分区前查询耗时 0.976s,增加分区后查询耗时 0.518s,可看到有 0.458s的增速
select * from `user_login_log` where user_id>=50001 and user_id<=100000;

4)key分区
按照KEY进行分区类似于按照HASH分区,除了HASH分区使用的用 户定义的表达式,而KEY分区的哈希函数是由MySQL服务器提供。

//添加字段 user_id(复合主键) 的key分区
ALTER table `user_login_log`  PARTITION BY HASH (`user_id`) PARTITIONS 10;//查询语句,增加分区前查询耗时 0.976s,增加分区后查询耗时 0.613s,可看到有 0.363s的增速
select * from `user_login_log` where user_id>=50001 and user_id<=100000;

5)子分区
子分区是分区表中每个分区的再次分割,目前只有RANGE和LIST分区的表可以再进行子分区,子分区只能是HASH或者KEY分区。这也被称为复合分区(composite partitioning)

//添加字段 user_id(复合主键) 的子分区
ALTER table `user_login_log`  PARTITION BY RANGE (`user_id`) SUBPARTITION BY HASH (`user_id`)(PARTITION p0 VALUES LESS THAN (101000) (SUBPARTITION s0,SUBPARTITION s1), PARTITION p1 VALUES LESS THAN (201000) (SUBPARTITION s2,SUBPARTITION s3),PARTITION p2 VALUES LESS THAN (301000) (SUBPARTITION s4,SUBPARTITION s5),PARTITION p3 VALUES LESS THAN (401000) (SUBPARTITION s6,SUBPARTITION s7),PARTITION p4 VALUES LESS THAN (501000) (SUBPARTITION s8,SUBPARTITION s9),PARTITION p5 VALUES LESS THAN (601000) (SUBPARTITION s10,SUBPARTITION s11),PARTITION p6 VALUES LESS THAN (701000) (SUBPARTITION s12,SUBPARTITION s13),PARTITION p7 VALUES LESS THAN (801000) (SUBPARTITION s14,SUBPARTITION s15),PARTITION p8 VALUES LESS THAN (901000) (SUBPARTITION s16,SUBPARTITION s17),PARTITION p9 VALUES LESS THAN MAXVALUE(SUBPARTITION s18,SUBPARTITION s19)
);//查询语句,增加分区前查询耗时 0.976s,增加分区后查询耗时 0.113s,可看到有 0.863s的增速
select * from `user_login_log` where user_id>=50001 and user_id<=100000;

2.3 分区的其他操作

//删除分区
ALTER TABLE `user_login_log` REMOVE PARTITIONING;//删除分区的某部分
ALTER table `user_login_log` DROP  PARTITION p1;

相关内容

热门资讯

前端-session、jwt 目录:   (1)session (2&#x...
linux入门---制作进度条 了解缓冲区 我们首先来看看下面的操作: 我们首先创建了一个文件并在这个文件里面添加了...
关于测试,我发现了哪些新大陆 关于测试 平常也只是听说过一些关于测试的术语,但并没有使用过测试工具。偶然看到编程老师...
前缀和与对数器与二分法 1. 前缀和 假设有一个数组,我们想大量频繁的去访问L到R这个区间的和,...
nodejs:本地安装nvm实... 一、背景-使用不同版本node的原因 vue3+ts、nuxt3版本,node...
JAVA集合知识整理 Java集合知识整理 HashMap相关 HashMap的底层数据结构:jdk1.8之...
无刷直流电机介绍及单片机控制实... 无刷直流电机介绍及单片机控制实例前言基本概念优势与劣势使用寿命基本结构使用单片机控制实例电子调速器&...
fwdiary(2) dp2 1.传纸条  AcWing 275. 传纸条 - AcWing 走两条路,走一条最大的...
常用的DOS命令 常用的DOS命令 DOS(Disk Operating System,磁...
<C++> 类和对象(下) 1.const成员函数将const修饰的“成员函数”称之为const成员函数,cons...