共计 4002 个字符,预计需要花费 11 分钟才能阅读完成。
这篇文章主要介绍“mysql 支持分区吗”,在日常操作中,相信很多人在 mysql 支持分区吗问题上存在疑惑,丸趣 TV 小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”mysql 支持分区吗”的疑惑有所帮助!接下来,请跟着丸趣 TV 小编一起来学习吧!
mysql 从 5.1 版本开始支持分区功能。MySQL5.1 中分区表达式必须是整数,或者返回整数的表达式;而 MySQL5.5 中提供了非整数表达式分区的支持。MySQL 数据库的分区是局部分区索引,一个分区中既存了数据,又放了索引;也就是说,每个区的聚集索引和非聚集索引都放在各自区的(不同的物理文件)。MySQL 支持 4 种分区类型:RANGE 分区,LIST 分区,HASH 分区,KEY 分区。
本教程操作环境:windows7 系统、mysql8 版本、Dell G3 电脑。
mysql 支持分区。
mysql 分区概述
MySQL 在 5.1 时添加了对水平分区的支持。分区是将一个表或索引分解成多个更小,更可管理的部分。每个区都是独立的,可以独立处理,也可以作为一个更大对象的一部分进行处理。这个是 MySQL 支持的功能,业务代码无需改动。要知道 MySQL 是面向 OLTP 的数据,它不像 TIDB 等其他 DB。那么对于分区的使用应该非常小心,如果不清楚如何使用分区可能会对性能产生负面的影响。
MySQL 数据库的分区是局部分区索引,一个分区中既存了数据,又放了索引。也就是说,每个区的聚集索引和非聚集索引都放在各自区的(不同的物理文件)。目前 MySQL 数据库还不支持全局分区。
无论哪种类型的分区,如果表中存在主键或唯一索引时,分区列必须是唯一索引的一个组成部分。
分区表的限制因素
(1)、一个表最多只能有 1024 个分区。
(2)、MySQL5.1 中,分区表达式必须是整数,或者返回整数的表达式。在 MySQL5.5 中提供了非整数表达式分区的支持。
(3)、如果分区字段中有主键或者唯一索引的列,那么多有主键列和唯一索引列都必须包含进来。即:分区字段要么不包含主键或者索引列,要么包含全部主键和索引列。
(4)、分区表中无法使用外键约束。
(5)、MySQL 的分区适用于一个表的所有数据和索引,不能只对表数据分区而不对索引分区,也不能只对索引分区而不对表分区,也不能只对表的一部分数据分区。
分区类型
目前 MySQL 支持一下几种类型的分区,RANGE 分区,LIST 分区,HASH 分区,KEY 分区。如果表存在主键或者唯一索引时,分区列必须是唯一索引的一个组成部分。实战十有八九都是用 RANGE 分区。
RANGE 分区
RANGE 分区是实战最常用的一种分区类型,行数据基于属于一个给定的连续区间的列值被放入分区。但是记住,当插入的数据不在一个分区中定义的值的时候,会抛异常。
RANGE 分区主要用于日期列的分区,比如交易表啊,销售表啊等。可以根据年月来存放数据。如果你分区走的唯一索引中 date 类型的数据,那么注意了,优化器只能对 YEAR(),TO_DAYS(),TO_SECONDS(),UNIX_TIMESTAMP() 这类函数进行优化选择。实战中可以用 int 类型,那么只用存 yyyyMM 就好了。也不用关心函数了。
CREATE TABLE `m_test_db`.`Order` (
`id` INT NOT NULL AUTO_INCREMENT,
`partition_key` INT NOT NULL,
`amt` DECIMAL(5) NULL,
PRIMARY KEY (`id` , `partition_key`)
) PARTITION BY RANGE (partition_key) PARTITIONS 5 (PARTITION part0 VALUES LESS THAN (201901) ,
PARTITION part1 VALUES LESS THAN (201902) ,
PARTITION part2 VALUES LESS THAN (201903) ,
PARTITION part3 VALUES LESS THAN (201904) ,
PARTITION part4 VALUES LESS THAN (201905));
这时候我们先插入一些数据
INSERT INTO `m_test_db`.`Order` (`id`, `partition_key`, `amt`) VALUES ( 1 , 201901 , 1000
INSERT INTO `m_test_db`.`Order` (`id`, `partition_key`, `amt`) VALUES ( 2 , 201902 , 800
INSERT INTO `m_test_db`.`Order` (`id`, `partition_key`, `amt`) VALUES (3 , 201903 , 1200
现在我们查询一下,通过 EXPLAIN PARTITION 命令发现 SQL 优化器只需搜对应的区,不会搜索所有分区
如果 sql 语句有问题,那么会走所有区。会很危险。所以分区表后,select 语句必须走分区键。
以下 3 种不是太常用,就一笔带过了。
LIST 分区
LIST 分区和 RANGE 分区很相似,只是分区列的值是离散的,不是连续的。LIST 分区使用 VALUES IN,因为每个分区的值是离散的,因此只能定义值。
HASH 分区
说到哈希,那么目的很明显了,将数据均匀的分布到预先定义的各个分区中,保证每个分区的数量大致相同。
KEY 分区
KEY 分区和 HASH 分区相似,不同之处在于 HASH 分区使用用户定义的函数进行分区,KEY 分区使用数据库提供的函数进行分区。
分区和性能
一项技术,不是用了就一定带来益处。比如显式锁功能比内置锁强大,你没玩好可能导致很不好的情况。分区也是一样,不是启动了分区数据库就会运行的更快,分区可能会给某些 sql 语句性能提高,但是分区主要用于数据库高可用性的管理。
数据库应用分为 2 类,一类是 OLTP(在线事务处理),一类是 OLAP(在线分析处理)。对于 OLAP 应用分区的确可以很好的提高查询性能,因为一般分析都需要返回大量的数据,如果按时间分区,比如一个月用户行为等数据,则只需扫描响应的分区即可。在 OLTP 应用中,分区更加要小心,通常不会获取一张大表的 10% 的数据,大部分是通过索引返回几条数据即可。
比如一张表 1000w 数据量,如果一句 select 语句走辅助索引,但是没有走分区键。那么结果会很尴尬。如果 1000w 的 B + 树的高度是 3,现在有 10 个分区。那么不是要 (3+3)*10 次的逻辑 IO?(3 次聚集索引,3 次辅助索引,10 个分区)。所以在 OLTP 应用中请小心使用分区表。
在日常开发中,如果想查看 sql 语句的分区查询结果可以使用 explain partitions + select sql 来获取,partitions 标识走了哪几个分区。
mysql explain partitions select * from TxnList where startTime 2016-08-25 00:00:00 and startTime 2016-08-25 23:59:00
+----+-------------+-------------------+------------+------+---------------+------+---------+------+-------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------------+------------+------+---------------+------+---------+------+-------+-------------+
| 1 | SIMPLE | ClientActionTrack | p20160825 | ALL | NULL | NULL | NULL | NULL | 33868 | Using where |
+----+-------------+-------------------+------------+------+---------------+------+---------+------+-------+-------------+
1 row in set (0.00 sec)
注:
1.MySQL Workbench 下添加分区的截图
2. Table has no partition for value 12
在 12 月的某一天,我查看了生产的日志文件,忽然发现系统一直在报错:Table has no partition for value 12。仔细检查分区 sql 发现分区的时候用的是 less than
也就是说我在注释 1 截图里面的分区是不包括 12 月的区的。执行以下命令增加分区:
ALTER TABLE table_name ADD PARTITION (PARTITION p_12 VALUES LESS THAN (13));
如果没有进行适当的处理,将会报错。所以在进行 RANGE 分区时,要思考这种情况。一般情况下,就时在最后添加一个 MAXVALUE 分区,如下:
PARTITION p_max VALUES LESS THAN MAXVALUE
到此,关于“mysql 支持分区吗”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注丸趣 TV 网站,丸趣 TV 小编会继续努力为大家带来更多实用的文章!