一、MySQL分区简介

1、数据库分区

MySQL是一种常用的关系型数据库管理系统,分区表是一种在MySQL数据库中处理大规模数据的最佳方案之一,其主要目的是为了在特定的SQL操作中减少数据读写的总量以缩减SQL语句的响应时间。

分区表是指将表按照创建时所指定的规则(如按时间、按范围等)来进行分区,即将一个大表拆分成多个小表,每个小表称为一个分区,并且每个分区可以独立存储于不同的物理介质上,从而实现表的水平切分和分散。MySQL会根据查询条件自动选择对应的分区,从而提高查询效率和响应速度。

MYSQL的分区主要有两种形式:水平分区和垂直分区

①、水平分区(HorizontalPartitioning)

这种形式的分区是对根据表的行进行分区,通过这样的方式不同分组里面的物理列分割的数据集得以组合,从而进行个体分割(单分区)或集体分割(1个或多个分区)。

所有在表中定义的列在每个数据集中都能找到,所以表的特性依然得以保持。水平分区一定要通过某个属性列来分割。常见的比如年份,日期等。

②、垂直分区(VerticalPartitioning)

这种分区方式一般来说是通过对表的垂直划分来减少目标表的宽度,使某些特定的列被划分到特定的分区,每个分区都包含了其中的列所对应所有行。

分区说明:

1)可以用 show  variables like ‘%partition%’;命令查询当前的MySQL数据库版本是否支持分区。

2)在扫描操作中,MySQL优化器只扫描保护数据的那个分区以减少扫描范围获得性能的提高。

3)分区技术使得数据管理变得简单,删除某个分区不会对另外的分区造成影响,分区有系统直接管理不用手工干预。

4)MySQL从5.1版本开始支持分区。每个分区的名称是不区分大小写。同个表中的分区表名称要唯一。

5)分区表的每个分区可以使用不同的存储引擎。

2、分区表的优势

分区表技术有以下优势:

①、提高系统性能

当数据量巨大时,使用普通的表查询效率会非常低下,而使用分区表技术可以将数据按照特定的规则进行拆分,从而提高查询效率和响应速度。

②、快速处理海量数据

分区表技术可以将大表数据拆分成多个小表,每个小表可以单独进行操作,从而快速处理海量数据,提高系统性能。

③、节省存储空间

使用分区表技术可以将数据分散存储于不同的物理介质上,从而节省存储空间。

二、MySQL分区类型

根据所使用的不同分区规则可以分成几大分区类型。

1、RANGE 分区:

基于属于一个给定连续区间的列值,把多行分配给分区。

2、LIST 分区:

类似于按RANGE分区,区别在于LIST分区是基于列值匹配一个离散值集合中的某个值来进行选择。

3、HASH分区:

基于用户定义的表达式的返回值来进行选择的分区,该表达式使用将要插入到表中的这些行的列值进行计算。这个函数可以包含MySQL中有效的、产生非负整数值的任何表达式。

4、KEY分区:

类似于按HASH分区,区别在于KEY分区只支持计算一列或多列,且MySQL服务器提供其自身的哈希函数。必须有一列或多列包含整数值。

5、复合分区:

基于RANGE/LIST 类型的分区表中每个分区的再次分割。子分区可以是 HASH/KEY 等类型。

三、MySQL分区表常用操作示例

1、创建range分区

①、以部门员工表为例子

create table emp

(empno varchar(20) not null ,

empname varchar(20),

deptno int,

birthdate date,

salary int

)

partition by range(salary)

(

partition p1 values less than (1000),

partition p2 values less than (2000),

partition p3 values less than maxvalue

);

②、以员工工资为依据做例子。

create table emp

(empno varchar(20) not null ,

empname varchar(20),

deptno int,

birthdate date not null,

salary int

)

partition by range(year(birthdate))

(

partition p1 values less than (1980),

partition p2 values less than (1990),

partition p3 values less than maxvalue

);

以year(birthdate)表达式(计算员工的出生日期)作为范围分区依据。这里最值得注意的是表达式必须有返回值。

2、创建list分区

create table emp

(empno  varchar(20) not null ,

empname varchar(20),

deptno  int,

birthdate date not null,

salary int

)

partition by list(deptno)

(

partition p1 values in  (10),

partition p2 values in  (20),

partition p3 values  in  (30)

);

以部门作为分区依据,每个部门做一分区。

3、创建hash分区

HASH分区主要用来确保数据在预先确定数目的分区中平均分布。在RANGE和LIST分区中,必须明确指定一个给定的列值或列值集合应该保存在哪 个分区中;而在HASH分区中,MySQL 自动完成这些工作,你所要做的只是基于将要被哈希的列值指定一个列值或表达式,以及指定被分区的表将要被分割成的分区数量。

create table emp

(empno varchar(20) not null ,

empname varchar(20),

deptno int,

birthdate date not null,

salary int

)

partition by hash(year(birthdate))

partitions 4;

4、创建key分区

按照KEY进行分区类似于按照HASH分区,除了HASH分区使用的用户定义的表达式,而KEY分区的哈希函数是由MySQL 服务器提供,服务器使用其自己内部的哈希函数,这些函数是基于与PASSWORD()一样的运算法则。“CREATE TABLE …PARTITION BY KEY”的语法规则类似于创建一个通过HASH分区的表的规则。它们唯一的区别在于使用的关键字是KEY而不是HASH,并且KEY分区只采用一个或多个 列名的一个列表。

create table emp

(empno varchar(20) not null ,

empname varchar(20),

deptno int,

birthdate date not null,

salary int

)

partition by key(birthdate)

partitions 4;

5、创建复合分区

①、range - hash(范围哈希)复合分区

create table emp

(empno varchar(20) not null ,

empname varchar(20),

deptno int,

birthdate date not null,

salary int

)

partition by range(salary)

subpartition by hash(year(birthdate))

subpartitions 3

(

partition p1 values less than (2000),

partition p2 values less than maxvalue

);

②、range- key复合分区

create table emp

(empno varchar(20) not null ,

empname varchar(20),

deptno int,

birthdate date not null,

salary int

)

partition by range(salary)

subpartition by key(birthdate)

subpartitions 3

(

partition p1 values less than (2000),

partition p2 values less than maxvalue

);

③、list - hash复合分区

CREATE TABLE emp (

empno varchar(20) NOT NULL,

empname varchar(20) ,

deptno int,

birthdate date NOT NULL,

salary int

)

PARTITION BY list (deptno)

subpartition by hash(year(birthdate))

subpartitions 3

(

PARTITION p1 VALUES in  (10),

PARTITION p2 VALUES in  (20)

);

④、list - key 复合分区

CREATE TABLE empk (

empno varchar(20) NOT NULL,

empname varchar(20) ,

deptno int,

birthdate date NOT NULL,

salary int

)

PARTITION BY list (deptno)

subpartition by key(birthdate)

subpartitions 3

(

PARTITION p1 VALUES in  (10),

PARTITION p2 VALUES in  (20)

);

6、分区表的管理操作

①、删除分区:

alter table emp drop partition p1;

不可以删除hash或者key分区。

一次性删除多个分区,alter table emp drop partition p1,p2;

②、增加分区:

alter table emp add partition (partition p3 values less than (4000));

alter table empl add partition (partition p3 values in (40));

③、分解分区:

Reorganize  partition关键字可以对表的部分分区或全部分区进行修改,并且不会丢失数据。分解前后分区的整体范围应该一致。

alter table te

reorganize partition p1 into

(

partition p1 values less than (100),

partition p3 values less than (1000)

);

----不会丢失数据

④、合并分区:

Merge分区:把2个分区合并为一个。

alter table te

reorganize partition p1,p3 into

(partition p1 values less than (1000));

----不会丢失数据

⑤、重新定义hash分区表:

Alter table emp partition by hash(salary)partitions 7;

----不会丢失数据

⑥、重新定义range分区表:

Alter table emp partitionbyrange(salary)

(

partition p1 values less than (2000),

partition p2 values less than (4000)

);

----不会丢失数据

⑦、删除表的所有分区:

Alter table emp remove partitioning;

⑧、重建分区:

这和先删除保存在分区中的所有记录,然后重新插入它们,具有同样的效果。它可用于整理分区碎片。

ALTER TABLE emp rebuild partitionp1,p2;

⑨、优化分区:

如果从分区中删除了大量的行,或者对一个带有可变长度的行(也就是说,有VARCHAR,BLOB,或TEXT类型的列)作了许多修改,可以使用“ALTER TABLE … OPTIMIZE PARTITION”来收回没有使用的空间,并整理分区数据文件的碎片。

ALTER TABLE emp optimize partition p1,p2;

⑩、分析分区:

读取并保存分区的键分布。

ALTER TABLE emp analyze partition p1,p2;

1)、修补分区:

修补被破坏的分区。

ALTER TABLE emp repair partition p1,p2;

2)、检查分区:

可以使用几乎与对非分区表使用CHECK TABLE 相同的方式检查分区。

ALTER TABLE emp CHECK partition p1,p2;

这个命令可以告诉你表emp的分区p1,p2中的数据或索引是否已经被破坏。如果发生了这种情况,使用“ALTER TABLE … REPAIR PARTITION”来修补该分区。

7、MySQL分区表的局限性

在5.1版本中分区表对唯一约束有明确的规定,每一个唯一约束必须包含在分区表的分区键(也包括主键约束)。

CREATE TABLE emptt (

empno varchar(20) NOT NULL  ,

empname varchar(20),

deptno int,

birthdate date NOT NULL,

salary int ,

primary key (empno)

)

PARTITION BY range (salary)

(

PARTITION p1 VALUES less than (100),

PARTITION p2 VALUES less than (200)

);

这样的语句会报错。

MySQL Database Error: A PRIMARY KEY must include allcolumns in the table's partitioning function;

CREATE TABLE emptt (

empno varchar(20) NOT NULL  ,

empname varchar(20) ,

deptno int(11),

birthdate date NOT NULL,

salary int(11) ,

primary key (empno,salary)

)

PARTITION BY range (salary)

(

PARTITION p1 VALUES less than (100),

PARTITION p2 VALUES less than (200)

);

在主键中加入salary列就正常。

8、MySQL分区处理NULL值的方式

如果分区键所在列没有notnull约束。

如果是range分区表,那么null行将被保存在范围最小的分区。

如果是list分区表,那么null行将被保存到list为0的分区。

在按HASH和KEY分区的情况下,任何产生NULL值的表达式MySQL都视同它的返回值为0。

为了避免这种情况的产生,建议分区键设置成NOT NULL。

分区键必须是INT类型,或者通过表达式返回INT类型,可以为NULL。唯一的例外是当分区类型为KEY分区的时候,可以使用其他类型的列作为分区键( BLOB or TEXT 列除外)。

对分区表的分区键创建索引,那么这个索引也将被分区,分区键没有全局索引一说

只有RANG和LIST分区能进行子分区,HASH和KEY分区不能进行子分区。

临时表不能被分区

9、获取MySQL分区表信息的几种方法

1)、show create table 表名

可以查看创建分区表的create语句。

执行后,获得一个结果集,其中包含表的创建语句。在创建语句中,可以找到有关分区的信息,包括分区类型、分区键、分区定义。

2)、查看information_schema.partitions表

select

partition_name part,

partition_expression expr,

partition_description descr,

table_rows

from information_schema.partitions  where

table_schema = schema()

and table_name='test';

可以查看表具有哪几个分区、分区的方法、分区中数据的记录数等信息

3)、explain partitions select语句

通过此语句来显示扫描哪些分区,及他们是如何使用的。

show table status  like  'table_name'

可以查看表是不是分区表

10、分区表性能比较

①、创建两张表: part_tab(分区表),no_part_tab(普通表)

CREATE TABLEpart_tab

( c1 int defaultNULL, c2 varchar2(30) default NULL, c3 date not null)

PARTITION BYRANGE(year(c3))

(PARTITION p0VALUES LESS THAN (1995),

PARTITION p1 VALUESLESS THAN (1996) ,

PARTITION p2 VALUESLESS THAN (1997) ,

PARTITION p3 VALUESLESS THAN (1998) ,

PARTITION p4 VALUES LESS THAN (1999) ,

PARTITION p5 VALUESLESS THAN (2000) ,

PARTITION p6 VALUESLESS THAN (2001) ,

PARTITION p7 VALUESLESS THAN (2002) ,

PARTITION p8 VALUESLESS THAN (2003) ,

PARTITION p9 VALUESLESS THAN (2004) ,

PARTITION p10VALUES LESS THAN (2010),

PARTITION p11VALUES LESS THAN (MAXVALUE) );

CREATE TABLE no_part_tab

( c1 int defaultNULL, c2 varchar2(30) default NULL, c3 date not null);

②、用存储过程插入800万条数据

CREATE PROCEDUREload_part_tab()

begin

declare v int default 0;

while v < 8000000

do

insert into part_tab

values (v,'testingpartitions',adddate('1995-01-01',(rand(v)*36520)mod 3652));

set v = v + 1;

end while;

end;

insert into no_part_tab  select * from part_tab;

③、测试SQL性能

⑴、查询分区表:

selectcount() from part_tab where c3 > date '1995-01-01’and c3 < date ‘1995-12-31’;

⑵、查询普通表:

selectcount(*) from part_tab where c3 > date '1995-01-01’and c3 < date ‘1995-12-31’;

分区表的执行时间比普通表少70%。

⑶、通过explain语句来分析执行情况:

mysql>explain select count(*) from part_tab where c3 > date '1995-01-01’and c3 < date ‘1995-12-31’;

四、MySQL分区表的优化

分区表的优化需要关注以下几个方面:

(1)建立合适的索引

(2)避免全表扫描,尽可能使用WHERE条件限制记录范围

(3)尽量避免使用临时表和文件排序等操作

(4)定期清理历史数据

MySQL-分区表和分区介绍的更多相关文章

  1. MySQL分区表 非分区索引 无法使用

    在<高性能Mysql>这本书的‘如何使用分区’这一小章中,列举的常见问题中,有以下一个问题: 分区列和索引列不匹配 如果定义的索引列和分区列不匹配,会导致查询无法进行分区过滤.假设在列a上 ...

  2. MySQL 分区表各个分区的行数

    分区的信息是记录在information_schema.partitions 这个表里的.它不能直接定位行所在的分区,但它可查到每个分区中有多少行. 例子: select partition_name ...

  3. MySQL 分区表,为什么分区键必须是主键的一部分?

    随着业务的不断发展,数据库中的数据会越来越多,相应地,单表的数据量也会越到越大,大到一个临界值,单表的查询性能就会下降. 这个临界值,并不能一概而论,它与硬件能力.具体业务有关. 虽然在很多 MySQ ...

  4. MYSQL分区表功能测试简析

    1.查看Mysql版本是否支持分区  SHOW VARIABLES LIKE '%partition%';   +-------------------+-------+ | Variable_nam ...

  5. MySQL 分区介绍总结

    200 ? "200px" : this.width)!important;} --> 介绍 分区是指根据一定的规则将一个大表分解成多个更小的部分,这里的规则一般就是利用分区 ...

  6. mysql分区表之三:MySQL分区建索引[转]

    介绍 mysql分区后每个分区成了独立的文件,虽然从逻辑上还是一张表其实已经分成了多张独立的表,从“information_schema.INNODB_SYS_TABLES”系统表可以看到每个分区都存 ...

  7. MySQL分区 (分区介绍与实际使用)

    分区介绍: 一.什么是分区? 所谓分区,就是将一个表分成多个区块进行操作和保存,从而降低每次操作的数据,提高性能.而对于应用来说则是透明的,从逻辑上看只有一张表,但在物理上这个表可能是由多个物理分区组 ...

  8. Mysql --分区表(6)Hash分区

    HASH分区 HASH分区主要用来分散热点读,确保数据在预先确定个数的分区中尽可能平均分布.对一个表执行HASH分区时,MySQL会对分区键应用一个散列函数,以此确定数据应当放在N个分区中的哪个分区 ...

  9. mysql分区表之一:分区原理和优缺点【转】

    1.分区表的原理 分区表是由多个相关的底层表实现,这些底层表也是由句柄对象表示,所以我们也可以直接访问各个分区,存储引擎管理分区的各个底层表和管理普通表一样(所有的底层表都必须使用相同的存储引擎),分 ...

  10. mysql分区介绍

    http://www.cnblogs.com/chenmh/p/5644713.html 介绍 可以针对分区表的每个分区指定各自的存储路径,对于innodb存储引擎的表只能指定数据路径,因为数据和索引 ...

随机推荐

  1. 3 分钟将免费无限制的 Claude 2.0 接入任意 GPT 套壳应用,太香了!

    Claude 是 ChatGPT 的最强竞争对手,由 OpenAI 早期团队成员创建,目标就是打造出能 赶超 ChatGPT 的 AI.最新版的 Claude 2.0,能力已经开始领先 ChatGPT ...

  2. ApplicationContextAware 的理解和应用

    当我们在项目中获取某一个spring bean时,可以定义一个类,实现ApplicationContextAware  该接口,该接口可以加载获取到所有的 spring bean. package c ...

  3. Laravel组件化开发学习笔记

    组件化开发就是基于组件来进行迭代开发,而不是从零开始开发 1.语法基础 组件开发的基础语法是命名空间. 可以使用魔法常量__NAMESPACE__可以直接获取当前命名空间的名称的字符串. 例如: &l ...

  4. Ubuntu 安装 MinIO

    MinIO是一个开源的高性能对象存储解决方案,支持多种安装方式,本例仅介绍最基础的单机安装方式. 下载安装文件 直接从MinIO官网下载安装文件. 下载服务端 wget https://dl.min. ...

  5. [转帖]MySQL 8.2.0 GA

    https://cloud.tencent.com/developer/article/2353798 MySQL新的进化版8.2.0于2023年10月25日发行,让我们一起快速浏览一下该版本发生哪些 ...

  6. [转帖]读懂什么是RDMA

    https://blog.csdn.net/tony_vip?type=blog 一.什么是RDMA1.RDMA主要体现     2.如何理解RDMA和TCP技术的区别?3.使用RDMA的好处包括: ...

  7. [转帖]Docker限制容器的资源

      docker在默认运行容器的情况下,是不会对运行的容器进行资源限制的,在自己的实验环境的话是随便你怎么弄的,不过在生产中是一定会对docker运行的容器进行资源限制的,如果不限制的话在生产中会带来 ...

  8. [转帖]linux时间戳转换成时间指令_时间戳转换公式

    原文地址:http://wanping.blogbus.com/logs/28663569.html 1.时间戳转换为正常显示的时间格式 Freebsd 系统下: 转换命令为: date -r 111 ...

  9. ESXi重置密码以及修改网络IP地址的方法

    Study From https://www.cnblogs.com/mk21/p/15784082.html 前期公司有部分虚拟化的服务器因为只通过vCenter进行管理. 导致密码遗失. 最近因为 ...

  10. Object.defineProperty熬夜整理的用法,保证你看的明白!

    Object.defineProperty的基本使用 <script> let personObj={ name:'何西亚', sex:'男' } //我们想给这个对象添加一个属性 // ...