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高速缓存启动方法及参数详解(query_cache_size)
Jul 01 MySQL
MySql 缓存查询原理与缓存监控和索引监控介绍
Jul 02 MySQL
Mysql实现简易版搜索引擎的示例代码
Aug 30 MySQL
MYSQL 表的全面总结
Nov 11 MySQL
Mysql多层子查询示例代码(收藏夹案例)
Mar 31 MySQL
MySQL实现配置主从复制项目实践
Mar 31 MySQL
详解MySQL的主键查询为什么这么快
Apr 03 MySQL
为什么MySQL8新特性会修改自增主键属性
Apr 18 MySQL
MySQL 表锁定 LOCK和UNLOCK TABLES的 SQL语法
Apr 18 MySQL
pt-archiver 主键自增
Apr 26 MySQL
MySQL数据库中的锁、解锁以及删除事务
May 06 MySQL
SQL中去除重复数据的几种方法汇总(窗口函数对数据去重)
May 08 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/08 其他游戏
浅析PHP的ASCII码转换类
2013/07/05 PHP
10条php编程小技巧
2015/07/07 PHP
Web层改进II-用xmlhttp 无声息提交复杂表单
2007/01/22 Javascript
JavaScript 应用类库代码
2008/06/02 Javascript
24款非常有用的 jQuery 插件分享
2011/04/06 Javascript
jQuery 鼠标经过(hover)事件的延时处理示例
2014/04/14 Javascript
简介JavaScript中setUTCSeconds()方法的使用
2015/06/12 Javascript
基于canvas实现的绚丽圆圈效果完整实例
2016/01/26 Javascript
AngularJs expression详解及简单示例
2016/09/01 Javascript
jQuery实现弹幕效果
2017/02/17 Javascript
实例解析js中try、catch、finally的执行规则
2017/02/24 Javascript
vue.js利用Object.defineProperty实现双向绑定
2017/03/09 Javascript
基于JavaScript实现焦点图轮播效果
2017/03/27 Javascript
ES6中箭头函数的定义与调用方式详解
2017/06/02 Javascript
Angular实现可删除并计算总金额的购物车功能示例
2017/12/26 Javascript
基于Vuejs的搜索匹配功能实现方法
2018/03/03 Javascript
windows实现npm和cnpm安装步骤
2019/10/24 Javascript
《javascript设计模式》学习笔记三:Javascript面向对象程序设计单例模式原理与实现方法分析
2020/04/07 Javascript
[10:18]2018DOTA2国际邀请赛寻真——找回自信的TNCPredator
2018/08/13 DOTA
基于python的汉字转GBK码实现代码
2012/02/19 Python
python文件和目录操作方法大全(含实例)
2014/03/12 Python
零基础写python爬虫之urllib2使用指南
2014/11/05 Python
老生常谈Python序列化和反序列化
2017/06/28 Python
Python 微信爬虫完整实例【单线程与多线程】
2019/07/06 Python
python实现美团订单推送到测试环境,提供便利操作示例
2019/08/09 Python
浅析canvas元素的html尺寸和css尺寸对元素视觉的影响
2019/07/22 HTML / CSS
就业自荐信
2013/12/04 职场文书
期末自我鉴定
2014/01/23 职场文书
厂区绿化方案
2014/05/08 职场文书
小学生关于梦想的演讲稿
2014/08/22 职场文书
优秀团支部申报材料
2014/12/26 职场文书
党员身份证明材料
2015/06/19 职场文书
加薪申请书应该这样写!
2019/07/04 职场文书
高考要来啦!用Python爬取历年高考数据并分析
2021/06/03 Python
SQL实现LeetCode(176.第二高薪水)
2021/08/04 MySQL