目录
1. 分区概述
分区功能并不是在存储引擎层完成的,因此不是只有 InnoDB 存储引擎支持分区,常见的存储引擎 MyISAM、NDB 等都支持。但也并不是所有的存储引擎都支持,如CSV, FEDORATED, MERGE等就不支持。在使用分区功能前,应该对选择的存储引擎对分区的支持有所了解。MySQL数据库在5.1版本时添加了对分区的支持。分区的过程是将一个表或索引分解为多个更小、更可管理的部分。就访问数据库的应用而言,从逻辑上讲,只有一个表或一个索引,但是在物理上这个表或索引可能由数十个物理分区组成。每个分区都是独立的对象,可以独自处理,也可以作为一个更大对象的一部分进行处理。MySQL 数据库支持的分区类型为水平分区,并不支持垂直分区。此外,MySQL数据库的分区是局部分区索引,一个分区中既存放了数据又存放了索引。而全局分区是指,数据存放在各个分区中,但是所有数据的索引放在一个对象中。目前,MySQL 数据库还不支持全局分区。
注*: 1.水平分区,指将同一表中不同行的记录分配到不同的物理文件中。
2.垂直分区,指将同一表中不同列的记录分配到不同的物理文件中。
1.1 表分区
表分区是指根据一定规则,将数据库中的一张表分解成多个更小的,容易管理的部分。从逻辑上看,只有一张表,但是底层却是由多个物理分区组成。
简单来说:就是把一张表数据分块存储,提升索引的查询效率
当一个表中的数据量太大时,会面临两个问题,一是对数据的操作会变慢,比如select、join、update、delete时,会对全表操作;二是不便于存储,可能会出现剩余磁盘空间存储不下这张表的情况。而分区就可以在一定程度上解决这两个问题。
mysql数据库中的数据是以文件的形势存在磁盘上的,默认放在/mysql/data下面(可以通过my.cnf中的datadir来查看),一张表主要对应着三个文件,一个是frm存放表结构的,一个是myd存放表数据的,一个是myi存表索引的。如果一张表的数据量太大,则myd,myi也会很大,查找数据很慢,此时可以利用mysql的分区功能,在物理上将该表对应的三个文件,分割成许多个小块,如此在查找数据时,只要知道这条数据在哪一块,然后在那一块找就可以,不用全部查找。如果表的数据太大,可能一个磁盘放不下,这个时候,我们可以把数据分配到不同的磁盘里面去。
简要的说,分区就是将表物理截断,但在逻辑上依然是一个整体,开发人员在数据操作时仍然是对这个整体大表进行操作,之后由数据库底层自己去寻找对应的分区进行操作,数据库底层寻找分区这个过程对开发人员来说是透明的,这样在数据操作时可以只对特定分区操作以提高效率,存储时也可以将不同分区的物理文件分开存放。
注:当过滤条件为分区的字段时才会自动寻找分区,否则还是全表扫描
1.2 表分区与分表的区别
分表:指的是通过一定规则,将一张表分解成多张不同的表。比如将用户订单记录根据时间成多个表。
分表与分区的区别在于:分区从逻辑上来讲只有一张表,而分表则是将一张表分解成多张表。
1.3 表分区的好处
1. 存储更多。与单个磁盘或文件系统分区相比,可以存储更多的数据。
2. 便于删除。删除数据时,可以通过删除与那些数据有关的分区,很容易地删除那些数据。相反地,在某些情况下,添加新数据的过程又可以通过为那些新数据专门增加一个新的分区,来很方便地实现。
3. 查询优化。
(1)满足一个给定WHERE语句的数据可以只保存在一个或多个分区内,在查找时无需查找其他分区。因为分区可以在创建了分区表后进行修改,所以在第一次配置分区方案还不曾这么做时,可以重新组织数据,来提高常用查询的效率。
(2)聚合函数(例如SUM()、COUNT())的查询,可以很容易地进行并行处理。这种查询的一个简单例子如 “SELECT salesperson_id, COUNT (orders) as order_total FROM sales GROUP BY salesperson_id;”。通过“并行”,这意味着该查询可以在每个分区上同时进行,最终结果为总计所有分区得到的结果。
(3)通过跨多个磁盘来分散数据查询,获得更大的查询吞吐量。
1.4 分区表的限制因素
- 一个表最多只能又1024个分区,5.7版本时可以支持8196个分区。 8196个分区只8196个文件,linux中cd proc/1064/fd 文件描述符太多会影响io效率;还有ulimit -a 中open files最大可以同时打开1024个文件。可以修改,但是要和内存匹配,1G内存最多打开10万个文件。
- MySQL5.1中,分区表达式必须是整数或者是返回整数表达式,mysql5.5中,可以直接使用列进行分区。
- 如果分区字段中有主键或者唯一索引的列,那么所有主键列和唯一索引列都必须包含进来。即:分区字段要么不包含主键或者索引列,要么包含全部主键和索引列。(mysql技术内幕书中说,分区列是唯一索引的一个组成部分也可以,不需要整个唯一索引列都是分区列)
- 分区表中无法使用外键约束。
- MySQL的分区适用于一个表的所有数据和索引,不能只对表数据分区而不对索引分区,也不能只对索引分区而不对表分区,也不能只对表的一部分数据分区。
- 必须使用分区字段才行,不然分区查询就会失败。走所有分区。
2. 如何判断当前MySQL是否支持分区?
mysql> show plugins
即:看名为partition的插件是否为active,active表示支持分区。
并且同一个数据库,不同表支持分区可以是不同的存储引擎,但是表分区后所有的分区都必须和表使用相同引擎。
- MyISAM和InnoDB都支持分区。
- MySQL 8都无需插件即可支持分区,且只有InnoDB支持,MyISAM不支持分区。
- MySQL 5.7 的NDB支持分区有自己的规则。
- MySQL只支持水平分区,对垂直分区