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 相关文章推荐
SQL注入的实现以及防范示例详解
Jun 02 MySQL
浅谈MySQL 亿级数据分页的优化
Jun 15 MySQL
MySQL千万级数据表的优化实战记录
Aug 04 MySQL
MySQL修炼之联结与集合浅析
Oct 05 MySQL
mysql事务对效率的影响分析总结
Oct 24 MySQL
mysql聚集索引、辅助索引、覆盖索引、联合索引的使用
Feb 12 MySQL
一条 SQL 语句执行过程
Mar 17 MySQL
在MySQL中你成功的避开了所有索引
Apr 20 MySQL
MySQL 自动填充 create_time 和 update_time
May 20 MySQL
MySQL 原理与优化之Limit 查询优化
Aug 14 MySQL
MySQL count(*)统计总数问题汇总
Sep 23 MySQL
MySQL新手入门进阶语句汇总
Sep 23 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
星际争霸任务指南——虫族
2020/03/04 星际争霸
PHP对表单提交特殊字符的过滤和处理方法汇总
2014/02/18 PHP
php无限遍历文件夹示例分享
2014/03/04 PHP
php使用$_POST或$_SESSION[]向js函数传参
2014/09/16 PHP
thinkphp浏览历史功能实现方法
2014/10/29 PHP
PHP基于CURL进行POST数据上传实例
2014/11/10 PHP
php生成数字字母的验证码图片
2015/07/14 PHP
Zend Framework教程之资源(Resources)用法实例详解
2016/03/14 PHP
web 页面分页打印的实现
2009/06/22 Javascript
jQuery 源码分析笔记(7) Queue
2011/06/19 Javascript
前台js对象在后台转化java对象的问题探讨
2013/12/20 Javascript
理解javascript中的原型和原型链
2015/07/30 Javascript
基于Turn.js 实现翻书效果实例解析
2016/06/20 Javascript
Bootstrap Metronic完全响应式管理模板之菜单栏学习笔记
2016/07/08 Javascript
扩展Bootstrap Tooltip插件使其可交互的方法
2016/11/07 Javascript
js实现随机数字字母验证码
2017/06/19 Javascript
jQuery常用选择器详解
2017/07/17 jQuery
简单理解Vue中的nextTick方法
2018/01/30 Javascript
jQuery实现的手动拖动控制进度条效果示例【测试可用】
2018/04/18 jQuery
命令行批量截图Node脚本示例代码
2019/01/25 Javascript
React组件对子组件children进行加强的方法
2019/06/23 Javascript
[01:45]2014DOTA2 TI预选赛预选赛 大神专访第二弹!
2014/05/20 DOTA
谈谈如何手动释放Python的内存
2016/12/17 Python
用Python3创建httpServer的简单方法
2018/06/04 Python
详解Python做一个名片管理系统
2019/03/14 Python
Python 获取numpy.array索引值的实例
2019/12/06 Python
TensorFlow tf.nn.conv2d_transpose是怎样实现反卷积的
2020/04/20 Python
解决Python3.8运行tornado项目报NotImplementedError错误
2020/09/02 Python
C语言中一个结构不能包含指向自己的指针吗
2012/05/25 面试题
故宫导游词
2015/01/31 职场文书
2015年个人工作总结报告
2015/04/25 职场文书
MySQL 使用SQL语句修改表名的实现
2021/04/07 MySQL
Python快速优雅的批量修改Word文档样式
2021/05/20 Python
Java界面编程实现界面跳转
2022/06/16 Java/Android
TaiShan 200服务器安装Ubuntu 18.04的图文教程
2022/06/28 Servers
JS开发前端团队展示控制器来为成员引流
2022/08/14 Javascript