MariaDB 分区
InnoDB逻辑存储结构
首先要先介绍一下InnoDB逻辑存储结构和区的概念,它的所有数据都被逻辑地存放在表空间,表空间又由段,区,页组成。
segment(段)
常见的段有数据段、索引段、回滚段等,在InnoDB
存储引擎中,对段的管理都是由引擎自身所完成的
extent(区)
区是由连续的页组成的空间,无论页的大小怎么变,区的大小默认总是为1MB。为了保证区中的页的连续性,InnoDB
存储引擎一次从磁盘申请4-5个区,InnoDB
页的大小默认为16kb,即一个区一共有64(1MB/16kb=16)个连续的页。每个段开始,先用32页(page)大小的碎片页来存放数据,在使用完这些页之后才是64个连续页的申请。这样做的目的是,对于一些小表或者是undo类的段,可以开始申请较小的空间,节约磁盘开销。
page(页)
上图的page区域,也可以叫块。页是InnoDB
磁盘管理的最小单位。默认大小为16KB,可以通过参数innodb_page_size
来设置。常见的页类型有:数据页,undo页,系统页,事务数据页,插入缓冲位图页,插入缓冲空闲列表页,未压缩的二进制大对象页,压缩的二进制大对象页等。
分区概述
这里讲的分区,此“区”非彼“区”,这里讲的分区的意思是指将同一表中不同行的记录分配到不同的物理文件中,几个分区就有几个.idb文件,不是我们刚刚说的区。MySQL在5.1时添加了对水平分区的支持。分区是将一个表或索引分解成多个更小,更可管理的部分。每个区都是独立的,可以独立处理,也可以作为一个更大对象的一部分进行处理。这个是MySQL支持的功能,业务代码无需改动。要知道MySQL是面向OLTP的数据,它不像TIDB等其他DB。那么对于分区的使用应该非常小心,如果不清楚如何使用分区可能会对性能产生负面的影响。
MySQL数据库的分区是局部分区索引,一个分区中既存了数据,又放了索引。也就是说,每个区的聚集索引和非聚集索引都放在各自区的(不同的物理文件)。目前MySQL数据库还不支持全局分区。
无论哪种类型的分区,如果表中存在主键或唯一索引时,分区列必须是唯一索引的一个组成部分。
分区类型
Partitioning Types Overview - MariaDB Knowledge Base
RANGE分区
RANGE
分区类型用于为每个分区分配一个由分区表达式生成的值范围。范围必须有序、连续且不重叠。最小值总是包含在第一个范围内。最高值可能包含在最后一个范围内,也可能不包含在最后一个范围内。
这种分区方法的变体RANGE COLUMNS允许我们使用多个列和更多的数据类型。
RANGE Partitioning Type - MariaDB Knowledge Base
创建分区
CREATE TABLE `partition_test`.`range_partition` ( `id` INT NOT NULL AUTO_INCREMENT,`create_time` INT NOT NULL, `num` BIGINT NULL,PRIMARY KEY (`id`, `create_time`)
)
PARTITION BY RANGE (create_time) PARTITIONS 3
(PARTITION part0 VALUES LESS THAN (202101),PARTITION part1 VALUES LESS THAN (202102),PARTITION part2 VALUES LESS THAN (202103)
);
插入测试数据
INSERT INTO `partition_test`.`range_partition` (`id`, `create_time`, `num`) VALUES ('1', 202101, 500);
INSERT INTO `partition_test`.`range_partition` (`id`, `create_time`, `num`) VALUES ('2', 202102, 800);
INSERT INTO `partition_test`.`range_partition` (`id`, `create_time`, `num`) VALUES ('3', 202103, 1000);
通过EXPLAIN PARTITION
命令发现SQL优化器只需搜对应的区,不会搜索所有分区
EXPLAIN PARTITIONS SELECT * FROM `partition_test`.`range_partition` WHERE create_time = 202101
如果sql语句有问题,那么会走所有区。会很危险。所以分区表后,select语句必须走分区键
EXPLAIN PARTITIONS SELECT * FROM `partition_test`.`range_partition` WHERE num > 500
增加分区
alter table range_partition add partition (partition part3 values LESS THAN (202104));
删除分区
alter table range_partition drop partition part3;
List分区
类似于按RANGE分区,区别在于LIST分区是基于列值匹配一个离散值集合中的某个值来进行选择
LIST Partitioning Type - MariaDB Knowledge Base
创建分区
CREATE TABLE `partition_test`.`list_partition`
( `id` INT NOT NULL AUTO_INCREMENT, `hos_code` BIGINT NOT NULL, `name` VARCHAR (32) NULL, PRIMARY KEY (`id`, `hos_code`)
)
PARTITION BY LIST (hos_code)
(PARTITION part100 VALUES IN (100),PARTITION part200 VALUES IN (200),PARTITION part300 VALUES IN (300)
);
插入测试数据
INSERT INTO `partition_test`.`list_partition` (`hos_code`, `name`) VALUES (100, "张三");
INSERT INTO `partition_test`.`list_partition` (`hos_code`, `name`) VALUES (200, "李四");
INSERT INTO `partition_test`.`list_partition` (`hos_code`, `name`) VALUES (300, "李四");
通过EXPLAIN PARTITION
命令发现SQL优化器只需搜对应的区,不会搜索所有分区
EXPLAIN PARTITIONS SELECT * FROM `partition_test`.`list_partition` WHERE hos_code = 100
增加分区
alter table list_partition add partition (partition part400 values in (400));
删除分区
alter table list_partition drop partition part400;
HASH分区
HASH
分区是一种分区形式,其中服务器负责放置数据的分区,以确保分区之间的均匀分布。
它需要一个列值,或者一个基于列值的表达式,该列值是散列的,还需要将表划分到的分区数。
number_of_partitions
表达式需要返回一个非常量的确定整数。每次插入和更新都会对其求值,因此过于复杂的表达式可能会导致性能问题
是一个正整数,指定要将表划分到的分区数。如果省略PARTITIONS子句,则默认分区数为1。
创建分区
CREATE TABLE `partition_test`.`hash_partition`
( `name` VARCHAR (32) NULL, `birthdate` date NOT NULL
)
PARTITION BY HASH (YEAR(birthdate))
PARTITIONS 4;
插入测试数据
INSERT INTO `partition_test`.`hash_partition` (`name`, `birthdate`) VALUES ("张三", '2001-01-01');
INSERT INTO `partition_test`.`hash_partition` (`name`, `birthdate`) VALUES ("李四", '2002-02-02');
INSERT INTO `partition_test`.`hash_partition` (`name`, `birthdate`) VALUES ("王五", '2003-03-03');
INSERT INTO `partition_test`.`hash_partition` (`name`, `birthdate`) VALUES ("赵六", '2004-04-04');
通过EXPLAIN PARTITION
命令发现SQL优化器只需搜对应的区,不会搜索所有分区
EXPLAIN PARTITIONS SELECT * FROM `partition_test`.`hash_partition` WHERE birthdate = '2001-01-01'
增加分区
alter table hash_partition add partition (partition p4);
删除分区(只能在RANGE或者LIST分区时被删除)
DROP PARTITION can only be used on RANGE/LIST partitions
MariaDB 分区相关推荐
- Centos7 编译安装 Nginx、MariaDB、PHP
前言 本文主要大致介绍CentOS 7下编译安装Nginx.MariaDB.PHP.面向有Linux基础且爱好钻研的朋友.技艺不精,疏漏再所难免,还望指正. 环境简介: 系统: CentOS 7,最小 ...
- 淘宝内部分享:MySQL MariaDB性能优化
淘宝内部分享:MySQL & MariaDB性能优化 摘要:MySQL是目前使用最多的开源数据库,但是MySQL数据库的默认设置性能非常的差,必须进行不断的优化,而优化是一个复杂的任务, ...
- MariaDB Spider:实现MySQL横纵向扩展的小能手
什么是Spider? 当您的数据库不断增长时,您绝对需要考虑其他技术,如数据库分片.Spider 是 MariaDB 内置的一个可插拔用于 MariaDB/MySQL 数据库分片的存储引擎,充当应用服 ...
- Linux 第71天 mariadb backup and recovery
Linux 第71天 mariadb backup and recovery 时间: 20181013 欢迎访问我的博客: www.winthcloud.top 目录 备份和恢复 冷备实验 lvm快照 ...
- MariaDB存储引擎简介
目录 MariaDB存储引擎简介 存储引擎简述 简单介绍几个 MariaDB 的存储引擎 1.InnoDB/XtraDB 2.MyISAM 3.Aria 4.TokuDB 5.MyRocks 6.Co ...
- MariaDB 窗口函数row_number、rank介绍
MariaDB 窗口函数row_number.rank介绍 窗口函数概述 MariaDB 自10.2.2即支持窗口函数,这里介绍下部分这类函数的功能和区别,详见下文的案例说明.1 ROW_NUMBER ...
- MariaDB数据库日志
在日常生产中,各种服务应用的日志的主要作用就是记录服务的运行状态.启动记录等信息,但数据库的日志对于数据库而言是很重要的.数据库日志分为:事务.中继.错误.通用.慢查询和二进制日志,其中每种日志都 ...
- MariaDB Spider 数据库分库分表实践
分库分表
分库分表 一般来说,数据库分库分表,有以下做法: 按哈希分片:根据一条数据的标识计算哈希值,将其分配到特定的数据库引擎中: 按范围分片:根据一条数据的标识(一般是值),将其分配到特定的数据库引擎中: ...
- 二进制安装mysql 5.7、mariadb (附yum安装方式)
前言: 本文以mariadb为例进行讲解,安装mysql同理,并以通过测试.安装前查找系统已安装的相关包(rpm -qa|grep -e "mysql" -e "mari ...
最新文章
- 解决xcode ***is missing from working copy
- HTML4.0标准语法--字体
- 一个通过数据库镜像实现SPS 2003门户快速备份与恢复的操作手册
- gitee最多上传多大文件_H5移动端图片压缩上传,基于Jquery的前端,实现拍照上传,选择相册
- 利用Scala特征(trait)的堆叠操作特性进行切面编程
- Leet Code OJ 203. Remove Linked List Elements [Difficulty: Easy]
- 混淆视听的感脚(二)
- Logtail从入门到精通(二):开启日志采集之旅
- Navicat工具获取操作数据库和表的SQL语句
- rabbitmq 学习-2-安装
- css 列表相关的属性 列表前的小点点 0302
- python遵循什么协议_《Python网络爬虫》2.3 Robots协议的遵守方式
- mac bash file密码_MAC 常用命令汇总
- 笔记本安装CentOS环境
- 搭建一个属于自己的语音对话机器人
- 常见的人脸对齐方法 python
- Python语法基础14 pickle与json模块 异常处理
- 如何做一个2D 横版过关类游戏
- C++微信网页协议实现和应用
- android 9 申请动态权限android.permission.WRITE_EXTERNAL_STORAGE 允许后应用闪退