Mysql调整优化之四种分区方式以及组合分区


Posted in MySQL onApril 13, 2022

看这篇文章前需要先了解一下以下几个问题~

一、问题

1.分区是什么

分区:就是把一张表数据分块存储

目的:提升索引的查询效率

2.Mysql为什么要使用分区

先从数据分析

然后进行索引优化

然后引入分区

3.Mysql中分区原理

客户端---------> Id 和分区键进行比较------------->找到指定分区---------->和数据库查询一致

4.Mysql中分区局限

必须使用分区字段才行,不然分区查询就会失败。走所有分区。

目前Range是范围分区,但是有时候我们会发现。分区大小永远是静态的。

所以会存在一个分区表大小不均。如何让分区表大小均衡呢?

二、分区落地实现

1.Range分区

条件

  • Product-Partiton表

步骤

1、先创建Product-Partiton-Range

CREATE TABLE `product-Partiton-Range` (
	`Id` BIGINT(8) NOT NULL,
	`ProductName` CHAR(245) NOT NULL DEFAULT '1',
	`ProductId` CHAR(255) NOT NULL DEFAULT '1',
	`ProductDescription` CHAR(255) NOT NULL DEFAULT '1',
	`ProductUrl` CHAR(255) NOT NULL DEFAULT '1',
	PRIMARY KEY (`Id`),
	INDEX `ProductId` (`ProductId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
PARTITION BY RANGE (Id) PARTITIONS 3 (
PARTITION part0 VALUES LESS THAN (12980), 
PARTITION part1 VALUES LESS THAN (25960), 
PARTITION part2 VALUES LESS THAN MAXVALUE);

2、然后查询分区表

select * from product-Partiton-Range where Id = 25000

2.Hash分区

步骤

1、先创建Product-Partiton-Hash

CREATE TABLE `product-Partiton-Hash` (
    `Id` BIGINT(8) NOT NULL,
    `ProductName` CHAR(245) NOT NULL DEFAULT '1',
    `ProductId` CHAR(255) NOT NULL DEFAULT '1',
    `ProductDescription` CHAR(255) NOT NULL DEFAULT '1',
    `ProductUrl` CHAR(255) NOT NULL DEFAULT '1',
    PRIMARY KEY (`Id`),
    INDEX `ProductId` (`ProductId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
PARTITION BY HASH (Id) PARTITIONS 3;

Hash分区只能进行数字字段进行分区,无法进行字符字段进行分区。如果需要对字段值进行分区。

必须包含在主键字段内。

3.Key分区

步骤

1、先创建Product-Partiton-Key

CREATE TABLE `product-Partiton-Key` (
	`Id` BIGINT(8) NOT NULL,
	`ProductName` CHAR(245) NOT NULL DEFAULT '1',
	`ProductId` CHAR(255) NOT NULL DEFAULT '1',
	`ProductDescription` CHAR(255) NOT NULL DEFAULT '1',
	`ProductUrl` CHAR(255) NOT NULL DEFAULT '1',
	PRIMARY KEY (`Id`),
	INDEX `ProductId` (`ProductId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
PARTITION BY KEY (ProductName) PARTITIONS 3;

#建立复合主键
CREATE TABLE `product-Partiton-Key` (
	`Id` BIGINT(8) NOT NULL,
	`ProductName` CHAR(245) NOT NULL DEFAULT '1',
	`ProductId` CHAR(255) NOT NULL DEFAULT '1',
	`ProductDescription` CHAR(255) NOT NULL DEFAULT '1',
	`ProductUrl` CHAR(255) NOT NULL DEFAULT '1',
	PRIMARY KEY (`Id`),
	INDEX `ProductId` (`ProductId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
PARTITION BY KEY (ProductName) PARTITIONS 3;

以上分区都是一个特点:所有的分区必须连续和连续大小进行分区。

我们再来看一个场景:如何对商品订单分区。

4.Mysql中如何落地List分区

步骤

1、先创建Product-Partiton-List

CREATE TABLE `product-Partiton-List` (
    `Id` BIGINT(8) NOT NULL,
    `ProductName` CHAR(245) NOT NULL DEFAULT '1',
    `ProductId` CHAR(255) NOT NULL DEFAULT '1',
    `ProductDescription` CHAR(255) NOT NULL DEFAULT '1',
    `ProductUrl` CHAR(255) NOT NULL DEFAULT '1',
    `ProductStatus` int NOT NULL DEFAULT 0,
    PRIMARY KEY (`Id`),
    INDEX `ProductId` (`ProductId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
PARTITION BY LIST(ProductId) (
    PARTITION a VALUES IN (1,5,6),
    PARTITION b VALUES IN (2,7,8)
);

商品主键和商品名称进行分区。

5.Mysql中如何落地组合分区

步骤

CREATE TABLE `product-Partiton-flex` (
    `Id` BIGINT(8) NOT NULL,
    `ProductName` CHAR(245) NOT NULL DEFAULT '1',
    `ProductId` CHAR(255) NOT NULL DEFAULT '1',
    `ProductDescription` CHAR(255) NOT NULL DEFAULT '1',
    `ProductUrl` CHAR(255) NOT NULL DEFAULT '1',
    PRIMARY KEY (`Id`,`ProductName`),
    INDEX `ProductId` (`ProductId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
PARTITION BY RANGE (Id) PARTITIONS 3
SUBPARTITION BY KEY(ProductName)
  SUBPARTITIONS 2 (
    PARTITION p0 VALUES LESS THAN (12980),
    PARTITION p1 VALUES LESS THAN (25960),
    PARTITION p2 VALUES LESS THAN MAXVALUE
);

三、Mysql如何管理分区

1.删除分区

ALERT TABLE users DROP PARTITION p0; 
#删除分区 p0

2.重建分区

2.1RANGE 分区重建

ALTER TABLE users REORGANIZE PARTITION p0,p1 INTO (PARTITION p0 VALUES LESS THAN (6000000));  
#将原来的 p0,p1 分区合并起来,放到新的 p0 分区中。

2.2 LIST 分区重建

ALTER TABLE users REORGANIZE PARTITION p0,p1 INTO (PARTITION p0 VALUES IN(0,1,4,5,8,9,12,13));
#将原来的 p0,p1 分区合并起来,放到新的 p0 分区中。

2.3 HASH/KEY 分区重建

ALTER TABLE users REORGANIZE PARTITION COALESCE PARTITION 2; 
#用 REORGANIZE 方式重建分区的数量变成2,在这里数量只能减少不能增加。想要增加可以用 ADD PARTITION 方法。

3. 新增分区

3.1 新增 RANGE 分区

#新增一个RANGE分区
ALTER TABLE category ADD PARTITION (PARTITION p4 VALUES IN (16,17,18,19)
            DATA DIRECTORY = '/data8/data'
            INDEX DIRECTORY = '/data9/idx');

3.2 新增 HASH/KEY 分区

ALTER TABLE users ADD PARTITION PARTITIONS 8;   #将分区总数扩展到8个。

3.3 给已有的表加上分区

alter table results partition by RANGE (month(ttime)) 
(
PARTITION p0 VALUES LESS THAN (1),
PARTITION p1 VALUES LESS THAN (2) , 
PARTITION p2 VALUES LESS THAN (3) ,
PARTITION p3 VALUES LESS THAN (4) , 
PARTITION p4 VALUES LESS THAN (5) ,
PARTITION p5 VALUES LESS THAN (6) , 
PARTITION p6 VALUES LESS THAN (7) ,
PARTITION p7 VALUES LESS THAN (8) , 
PARTITION p8 VALUES LESS THAN (9) ,
PARTITION p9 VALUES LESS THAN (10) , 
PARTITION p10 VALUES LESS THAN (11),
PARTITION p11 VALUES LESS THAN (12),
PARTITION P12 VALUES LESS THAN (13) 
);

4.默认分区限制分区字段必须是主键(PRIMARY KEY)的一部分,去除此限制

[方法1] 使用ID:

mysql> ALTER TABLE np_pk
    ->     PARTITION BY HASH( TO_DAYS(added) )
    ->     PARTITIONS 4;
#ERROR 1503 (HY000): A PRIMARY KEY must include all columns in the table's partitioning function
mysql> ALTER TABLE np_pk
    ->     PARTITION BY HASH(id)
    ->     PARTITIONS 4;
Query OK, 0 rows affected (0.11 sec)
Records: 0 Duplicates: 0 Warnings: 0

[方法2] 将原有PK去掉生成新PK

mysql> alter table results drop PRIMARY KEY;
Query OK, 5374850 rows affected (7 min 4.05 sec)
Records: 5374850 Duplicates: 0 Warnings: 0

mysql> alter table results add PRIMARY KEY(id, ttime);
Query OK, 5374850 rows affected (7 min 4.05 sec)
Records: 5374850 Duplicates: 0 Warnings: 0

总结

到此这篇关于Mysql四种分区方式以及组合分区落地实现的文章就介绍到这了!

MySQL 相关文章推荐
Mysql基础知识点汇总
May 26 MySQL
虚拟机linux端mysql数据库无法远程访问的解决办法
May 26 MySQL
MYSQL 无法识别中文的永久解决方法
Jun 03 MySQL
MySQL的安装与配置详细教程
Jun 26 MySQL
MySQL令人大跌眼镜的隐式转换
Aug 23 MySQL
MySQL命令无法输入中文问题的解决方式
Aug 30 MySQL
MySQL数据库⾼可⽤HA实现小结
Jan 22 MySQL
MySQL数据库查询进阶之多表查询详解
Apr 08 MySQL
MySQL事务操作的四大特性以及并发事务问题
Apr 12 MySQL
MySQL安装失败的原因及解决步骤
Jun 14 MySQL
mysql函数之截取字符串的实现
Aug 14 MySQL
聊聊mysql都有哪几种分区方式
Apr 13 #MySQL
MySQL分区以及建索引的方法总结
Apr 13 #MySQL
MySQL分区路径子分区再分区
Apr 13 #MySQL
MySQL创建管理子分区
Apr 13 #MySQL
MySQL创建管理KEY分区
Apr 13 #MySQL
MySQL创建管理HASH分区
Apr 13 #MySQL
MySQL创建管理RANGE分区
Apr 13 #MySQL
You might like
通过文字传递创建的图形按钮
2006/10/09 PHP
利用PHP脚本在Linux下用md5函数加密字符串的方法
2015/06/29 PHP
PHP基于反射机制实现插件的可插拔设计详解
2016/11/10 PHP
Yii2实现中国省市区三级联动实例
2017/02/08 PHP
laravel 5.4中实现无限级分类的方法示例
2017/07/27 PHP
PHP基于递归实现的约瑟夫环算法示例
2017/08/27 PHP
Firefox和IE兼容性问题及解决方法总结
2013/10/08 Javascript
JQuery给元素绑定click事件多次执行的解决方法
2014/05/29 Javascript
jQuery获取动态生成的元素示例
2014/06/15 Javascript
javascript判断网页是关闭还是刷新
2015/09/12 Javascript
js+canvas简单绘制圆圈的方法
2016/01/28 Javascript
Angular2 (RC4) 路由与导航详解
2016/09/21 Javascript
JavaScript中全选、全不选、反选、无刷新删除、批量删除、即点即改入库(在yii框架中操作)的代码分享
2016/11/01 Javascript
jquery中关于bind()方法的使用技巧分享
2017/03/30 jQuery
值得分享和收藏的xmlplus组件学习教程
2017/05/05 Javascript
十大 Node.js 的 Web 框架(快速提升工作效率)
2017/06/30 Javascript
AngularJS实现的2048小游戏功能【附源码下载】
2018/01/03 Javascript
Nodejs下使用gm圆形裁剪并合成图片的示例
2018/02/22 NodeJs
vue 实现边输入边搜索功能的实例讲解
2018/09/16 Javascript
JQuery Ajax跨域调用和非跨域调用问题实例分析
2019/04/16 jQuery
Vue 中 a标签上href无法跳转的解决方式
2019/11/12 Javascript
Python+Django在windows下的开发环境配置图解
2009/11/11 Python
python实现用户登录系统
2016/05/21 Python
Python冲顶大会 快来答题!
2018/01/17 Python
python之django母板页面的使用
2018/07/03 Python
python学生管理系统
2019/01/30 Python
简单的Python调度器Schedule详解
2019/08/30 Python
python中如何进行连乘计算
2020/05/28 Python
HTML5自定义属性前缀data-及dataset的使用方法(html5 新特性)
2017/08/24 HTML / CSS
巴西宠物店在线:Geração Pet
2017/05/31 全球购物
Android面试宝典
2013/08/06 面试题
设计专业毕业生求职信
2014/06/25 职场文书
市场调研项目授权委托书范本
2014/10/04 职场文书
英文慰问信
2015/02/14 职场文书
大学生年度个人总结
2015/02/15 职场文书
Python之Matplotlib绘制热力图和面积图
2022/04/13 Python