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之DML语言
Apr 05 MySQL
MySQL 使用SQL语句修改表名的实现
Apr 07 MySQL
MySQL 数据丢失排查案例
May 08 MySQL
mysql对于模糊查询like的一些汇总
May 09 MySQL
为什么mysql字段要使用NOT NULL
May 13 MySQL
MySQL Router实现MySQL的读写分离的方法
May 27 MySQL
MySQL系列之八 MySQL服务器变量
Jul 02 MySQL
MySQL修炼之联结与集合浅析
Oct 05 MySQL
优化Mysql查询的示例
Apr 26 MySQL
MySQL脏读,幻读和不可重复读
May 11 MySQL
MySQL主从切换的超详细步骤
Jun 28 MySQL
SQLServer常见数学函数梳理总结
Aug 05 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
php获取mysql版本的几种方法小结
2008/03/25 PHP
PHP获取搜索引擎关键字来源的函数(支持百度和谷歌等搜索引擎)
2012/10/03 PHP
php以fastCGI的方式运行时文件系统权限问题及解决方法
2015/05/11 PHP
Laravel中为什么不使用blpop取队列详析
2018/08/01 PHP
laravel框架中控制器的创建和使用方法分析
2019/11/23 PHP
如何运行/调试你的PHP代码
2020/10/23 PHP
Javascript 日期对象Date扩展方法
2009/05/30 Javascript
JavaScript 对Cookie 操作的封装小结
2009/12/31 Javascript
jQuery获取css z-index在各种浏览器中的返回值
2010/09/15 Javascript
javascript格式化json显示实例分析
2015/04/21 Javascript
jQuery+ajax+asp.net获取Json值的方法
2016/06/08 Javascript
JavaScript学习小结之使用canvas画“哆啦A梦”时钟
2016/07/24 Javascript
浅谈JS正则表达式的RegExp对象和括号的使用
2016/07/28 Javascript
Javascript中关于Array.filter()的妙用详解
2016/12/04 Javascript
JS创建Tag标签的方法详解
2017/06/09 Javascript
基于构造函数的五种继承方法小结
2017/07/27 Javascript
微信小程序版翻牌小游戏
2018/01/26 Javascript
JavaScript函数式编程(Functional Programming)高阶函数(Higher order functions)用法分析
2019/05/22 Javascript
JS实现可控制的进度条
2020/03/25 Javascript
antd-mobile ListView长列表的数据更新遇到的坑
2020/04/08 Javascript
Python 列表(List)操作方法详解
2014/03/11 Python
Python 逐行分割大txt文件的方法
2017/10/10 Python
详解如何在python中读写和存储matlab的数据文件(*.mat)
2018/02/24 Python
在Python中增加和插入元素的示例
2018/11/01 Python
Python lxml解析HTML并用xpath获取元素的方法
2019/01/02 Python
解决Pymongo insert时会自动添加_id的问题
2020/12/05 Python
利用Opencv实现图片的油画特效实例
2021/02/28 Python
澳大利亚最受欢迎的女士度假服装:Kabana Shop
2020/10/10 全球购物
屈臣氏越南官网:Watsons越南
2021/01/14 全球购物
高等教育专业自荐信范文
2014/03/26 职场文书
企业法人代表任命书
2014/06/06 职场文书
护士找工作求职信
2014/07/02 职场文书
地道战观后感2000字
2015/06/04 职场文书
浅谈node.js中间件有哪些类型
2021/04/29 Javascript
微信小程序基础教程之echart的使用
2021/06/01 Javascript
JavaScript parseInt0.0000005打印5原理解析
2022/07/23 Javascript