mysql分区是什么东西

引入

        最近刚被交接了一个用于记录日志的mysql数据库(具体做啥的其实俺也不清楚),便收到了db管理员亲切的问候,“喂,你们数据库磁盘使用80%了,快处理!”。我心头一惊,急问同事以前是如何处理的,同事微微一笑,“我们都是手动删一下数据就行了”,旋即交给我一行命令

alter table log01 drop partition p20190902;

        于是乎,我到机房一通操作,删了一大批数据,db管理员看着24%的磁盘使用,笑着对我竖起了大拇指。我也和他相视一笑,一切尽在不言中。事情告一段落,但某天午夜梦回,突然意识到,其实我根本不知道partition是什么,有什么用。于是挑灯夜战,四处百度,再CV大法,做个记录。

概述

        当遇到大数据量数据时,单表已经很难覆盖,我们通常会考虑分库或者分表,但分区,也不失为一种解决方案。

        分区的原理也很简单弱智,我们以InnoDB为例,普通的表数据,会存储在.idb文件中,分区则是根据一定的分区逻辑,将同一表中不同行的记录分配到不同的物理文件中,几个分区就有几个.idb文件。如果搜索条件包含了分区键,sql会自动根据分区逻辑,仅去对应的分区文件中查找结果。如果没有包含,那对不起,我只好去所有文件里面找一圈,和遍历多张表不会有本质区别。

        设置好分区后,我们可以使用explain partitons select xxxxx语句来查看一句select语句走了几个分区。示例如下:

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 |  
+----+-------------+-------------------+------------+------+---------------+------+---------+------+-------+-------------+  
row in set (0.00 sec)

        其他一些常见的分区命令如下:

alter table xxxxxxx add partition (partition p0 values less than(1991));  //添加分区
alter table xxxxxxx drop partition p0; //删除分区
alter table xxxxxx truncate partition p1,p2; 
或 alter table xxxxxx truncate partition all; 
或 delete from xxxxxx where separated < '2006-01-01' or (separated >= '2006-01-01' and separated<'2011-01-01'); //删除分区数据

分区的分类

        目前MySQL支持范围分区(RANGE),列表分区(LIST),哈希分区(HASH)以及KEY分区四种。如果表存在主键或者唯一索引时,分区列必须是唯一索引的一个组成部分。实战十有八九都是用RANGE分区。

RANGE分区

  RANGE分区是实战最常用的一种分区类型,行数据基于属于一个给定的连续区间的列值被放入分区。但是记住,当插入的数据不在一个分区中定义的值的时候,会抛异常。RANGE分区主要用于日期列的分区,比如交易表啊,销售表啊等。可以根据年月来存放数据。如果你分区走的唯一索引中date类型的数据,那么注意了,优化器只能对YEAR(),TO_DAYS(),TO_SECONDS(),UNIX_TIMESTAMP()这类函数进行优化选择。

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语句必须走分区键。

        备注:以上实例来自参考文档1

以下3种不是太常用,就简单带过了。

LIST分区

        LIST分区和RANGE分区很相似,区别在于LIST是枚举值列表的集合,RANGE是连续的区间值的集合。二者在语法方面非常的相似。

HASH分区

        HASH分区只能针对整数进行HASH,对于非整形的字段只能通过表达式将其转换成整数。表达式可以是mysql中任意有效的函数或者表达式,对于非整形的HASH往表插入数据的过程中会多一步表达式的计算操作,所以不建议使用复杂的表达式这样会影响性能。

KEY分区

        KEY分区其实跟HASH分区差不多,不同点如下:KEY分区允许多列,而HASH分区只允许一列。如果在有主键或者唯一键的情况下,key中分区列可不指定,默认为主键或者唯一键,如果没有,则必须显性指定列。KEY分区对象必须为列,而不能是基于列的表达式。

使用场景&分区分表区别

  • 分表和分区不矛盾,是可以相互配合的,对于那些大访问量,并且表数据比较多的表,我们可以采取分表和分区结合的方式。
  • 分表的方法有很多,部分分表手段,需要在代码端写逻辑,决定查询哪个表;分区的实现则相对简单,对代码端来说是透明的。
  • 如果数据量过大,已经突破了单机限制,一定是考虑分表。
  • 对于大部分OLTP(在线事务处理)场景,考虑分表。通常这类处理仅需要返回少量指定数据,很难和分区键配合上。
  • 对于大部分OLAP(在线分析处理)场景,考虑分区。一般分析都需要返回大量的数据,如果按时间分区,比如一个月用户行为等数据,则只需扫描响应的分区即可。

参考文档

搞懂MySQL分区,搞懂MySQL分区 - GrimMjx - 博客园

MySql分库分表与分区的区别和思考,MySql分库分表与分区的区别和思考 - GrimMjx - 博客园

实战mysql分区(PARTITION),https://www.iteye.com/blog/lobert-1955841

<Mysql> 深入理解MySQL分区(Partition),<Mysql> 深入理解MySQL分区(Partition) - 简书

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值