---
title: 不懂SQL优化?那你就OUT了(九)
MySQL如何优化-- 分区(一)
date: 2018-12-30
categories: 数据库优化
---
这篇博客我们将谈论一下mysql的分区。
##分区的概述
SQL标准在数据存储的物理方面没有提供太多的指导。SQL语言本身旨在使其独立于它所使用的数据结构、表、行或列下的任何数据结构。尽管如此,大部分高级数据库管理系统已经开发了一些根据文件系统、硬件或者这两者来确定将要用于存储特定数据块物理位置的方法。在MySQL中, InnoDB存储引擎一直支持表空间的概念,并且MySQL服务器在引入分区之前,可以通过配置来使用不同的物理目录来存储不同的数据库数据。
分区使这一概念更进一步,分区允许您通过<font style="color:coral">设置需要的规则</font>在文件系统中分布存储单个表的各个部分。实际上就是<font style="color:coral">表的不同部分作为单独的表存储在不同的位置</font>。用户所选择的、实现<font style="color:coral">数据分割的规则</font>被称为分区函数,在MySQL中它可以是模数,或者是简单的匹配一个连续的数值区间或数值列表,或者是一个内部HASH函数,或线性哈希函数。分区函数根据用户指定的分区类型来选择,并将用户提供的表达式的值作为其参数,该表达式可以是列值、作用于一个或多个列值的函数,也可以是一组一个或多个列值,具体取决于所使用的分区类型。
分区有分为两种分区:
1.水平分区:就是把表的不同行可以分配给不同的物理分区。
2.垂直分区:就是把表的不同列被分配到不同的物理分区。
注意:最新的 MySQL 8.0不支持垂直分区,目前还没有将垂直分区引入MySQL的计划。
要创建分区表,必须使用支持分区表的存储引擎。在MySQL 8.0中,相同分区表的所有分区必须使用相同的存储引擎。
在MySQL 8.0中,唯一支持分区的存储引擎是InnoDB和NDB。分区不能与不支持分区的存储引擎一起使用;这些引擎包括MyISAM、MERGE、CSV和 FEDERATED 存储引擎。
在创建分区表时,与创建任何其他表一样,使用默认存储引擎。如果要覆盖此行为,只需要像对未分区的表使用[STORAGE] ENGINE选项。目标存储引擎必须支持分区,否则语句将失败。您应该记住,在CREATE table语句中使用任何分区选项之前,都需要列出[STORAGE]引擎(和其他表选项)。
> 特别注意:
>
> 分区适用于表的所有数据和索引;不能只分区数据而不分区索引,反之亦然,也不能只分区表的一部分。
案列: 以使用range分区为例,以员工的年龄为分区
CREATE TABLE t_employee(
eId INT, -- 员工编号
eName VARCHAR(10) NOT NULL, -- 员工姓名
eAge INT NOT NULL -- 员工年龄
)ENGINE=INNODB
PARTITION BY RANGE (eAge)(
PARTITION p0 VALUES LESS THAN (30),
PARTITION p1 VALUES LESS THAN (40),
PARTITION p2 VALUES LESS THAN (50),
PARTITION p3 VALUES LESS THAN (60)
);
建表成功后查看表的数据文件
简单理解分区: MYSQL的分区就是在物理上将一张表的文件,分割成许多个小块(分区),我们查找一条数据时,就不用全部查找,只要知道这条数据在哪一块(分区),然后在那一块(分区)找就行了。如果表的数据太大,可能一个磁盘放不下,这个时候,我们可以把数据分配到不同的磁盘里面去。
###分区的一些优点:
1. 与单个磁盘或文件系统分区相比,可以存储更多的数据。
2. 对于那些已经失去保存意义的数据,通常可以通过删除与那些数据有关的分区,很容易地删除那些数据。 相反地,在某些情况下,添加新数据的过程又可以通过为那些新数据专门增加一个新的分区,来很方便地实现。
3. 一些查询可以得到极大的优化。因为满足给定WHERE子句的数据只能存储在一个或多个分区上,这样在查找时就不用查找其他剩余的分区。因为可以在创建分区表之后更改分区,所以可以重新组织数据,以增强分区模式首次设置时可能不经常使用的频繁查询。
4. MySQL(8.0)支持查询的显式分区选择, 例如:SELECT * FROM t PARTITION (p0,p1) WHERE c <5,其中c < 5只选择与WHERE条件匹配的分区p0和p1中的那些行。在这种情况下,MySQL不会检查表t的任何其他分区;当您已经知道希望检查哪个或哪些分区时,这可以极大地加快查询速度。数据修改语句DELETE、INSERT、REPLACE、UPDATE也支持分区选择。
##分区类型
MySQL 8.0中可用的分区类型。包括下面列出的类型:
1. RANGE分区(范围分区):这种类型的分区根据给定范围内的 列值 将行分配给分区。
2. LIST分区(列表分区):类似于范围分区,区别在于LIST分区是基于 列值 匹配 一个离散值集合中的某个值来进行选择。
3. HASH分区:对于这种类型的分区,是基于用户定义的表达式的返回值来进行选择的分区,该表达式使用将要插入到表中的这些 行的列值 进行计算。这个函数可以包含MySQL 中有效的、产生非负整数值的任何表达式。
4. KEY分区:类似于按HASH分区,区别在于KEY分区只支持计算一列或多列,且MySQL 服务器提供其自身的哈希函数。必须有一列或多列包含整数值。
无论使用何种类型的分区,分区总是在创建时就自动的顺序编号,且从0开始记录,记住这一点非常重要。当有一新行插入到一个分区表中时,就是使用这些分区编号来识别正确的分区。例如,如果你的表使用4个分区,那么这些分区的编号为0, 1, 2, 和3。对于RANGE和LIST分区类型,确认每个分区编号都定义了一个分区,很有必要。对HASH分区,使用的用户函数必须返回一个大于0的整数值。对于KEY分区,这个问题通过MySQL服务器内部使用的 哈希函数自动进行处理。
分区的名称通常遵循MySQL标识符的规则,例如表和数据库的标识符。但是,您应该注意到 <font style='color:coral'>分区名不区分大小写</font>。
mysql> CREATE TABLE t2 (val INT)
-> PARTITION BY LIST(val)(
-> PARTITION mypart VALUES IN (1,3,5),
-> PARTITION MyPart VALUES IN (2,4,6)
-> );
ERROR 1488 (HY000): Duplicate partition name mypart