00.序言
业务上面老是需要划分区,按照分区去查表,总是有个模糊的印象觉得分区可以帮助查询的速度更快,但一直不太明白是如何快,底层逻辑是什么,跟索引有什么区别。今天终于要好好学习一下了!
01.分区是什么?
?
02.优点
- 非常方便的增加或者删除跟分区有关的数据(就是往对应文件里面插入或者删除嘛)
- 在查询的时候,只用在有限的几个分区找,就不用找其他不相干的分区了
- sum()或者count()这样的聚合函数,每个分区可以并行处理,极大的提高效率
- 可以跨磁盘分散查询,提高效率
03.缺点/限制
- 一个MySQL表只支持1024个分区(如果是用日期来存数据,超过两年半,数据该怎么办?答曰:重置分区,把一年前的数据合在一起存,留给新许多空间日期)
- 如果分区字段中有主键或者唯一索引列,那就要把其他主键/唯一索引列也包括进来,要么不包,要么全包
- 性能上面,分区也是会消耗内存资源和CPU的运行的,所以分区还需科学的判断
04.怎么建分区
分区需要在建表的时候就分好,如果后面想更改....(emmm,建一个相同的表结构,然后insert into 分区表 select * from 原表)
create table news(
Title varchar(100) not null,
Message varchar(500) not null,
Createdtime date not null,
Source varchar(20),
Link varchar(100)
)
partition by range columns(Createdtime)(
partition pt0 values less than ('2016-01-01'),
partition pt1 values less than ('2017-01-01'),
partition pt2 values less than ('2018-01-01'),
partition pt3 values less than ('2019-01-01'),
partition pt4 values less than ('2020-01-01'),
partition pt5 values less than ('2021-01-01'),
partition pt6 values less than ('2022-01-01'),
partition pt7 values less than maxvalue ## 这相当于一个包尾的句子
)
如果要更改表分区
ALTER TABLE news ADD PARTITION (PARTITION p8 VALUES LESS THAN ('2023-01-01'));
VALUES LESS THAN value must be strictly increasing for each partition TraceId : 0bc059b716381962812667522e19ab
会报以上错误,需要先删除那条包尾的pt7分区,然后再加上新分区(达咩!千万不要,删除分区的话,会把分区的整个文件给删了,那是妥妥的删库跑路啊)
正确方案是把原来的分区裂成多个
## 追加,就是把原来的一个分区裂成多个
ALTER TABLE news reorganize partition pt7 into (
partition pt7 values less than ('2023-01-01'),
partition pt8 values less than maxvalue
)
show create table news;
## 以下是show返回的结果
CREATE TABLE `news` (
`Title` varchar(100) NOT NULL,
`Message` varchar(500) NOT NULL,
`Createdtime` date NOT NULL,
`Source` varchar(20) DEFAULT NULL,
`Link` varchar(100) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
/*!50500 PARTITION BY RANGE COLUMNS(Createdtime)
(PARTITION pt0 VALUES LESS THAN ('2016-01-01') ENGINE = InnoDB,
PARTITION pt1 VALUES LESS THAN ('2017-01-01') ENGINE = InnoDB,
PARTITION pt2 VALUES LESS THAN ('2018-01-01') ENGINE = InnoDB,
PARTITION pt3 VALUES LESS THAN ('2019-01-01') ENGINE = InnoDB,
PARTITION pt4 VALUES LESS THAN ('2020-01-01') ENGINE = InnoDB,
PARTITION pt5 VALUES LESS THAN ('2021-01-01') ENGINE = InnoDB,
PARTITION pt6 VALUES LESS THAN ('2022-01-01') ENGINE = InnoDB,
PARTITION pt7 VALUES LESS THAN ('2023-01-01') ENGINE = InnoDB,
PARTITION pt8 VALUES LESS THAN (MAXVALUE) ENGINE = InnoDB) */
|