OBCP第四章 SQL调优-分区

简介: OBCP第四章 SQL调优-分区

分区表概述

OceanBase数据库把普通的表的数据按照一定的规则划分到不同的区块内,同一区块的数据物理上存储在一起。这种划分区块的表叫做分区表,其中的每一个区块称作分区。分区技术是非常重要的分布式能力之一,它能解决大表的容量问题和并发访问时性能问题。普通的表只有一个分区,可以看作分区表的特例。每个分区只能存在于一个节点内部,分区表的不同分区可以分散在不同节点上。


创建分区的目的是为了在特定的SQL操作中减少数据读写的总量以减少响应时间:


可扩展性,可管理性,提高性能

OceanBase分区表特点

可多机扩展

提高可管理性

提高性能

自动负载均衡、自动容灾

对业务透明,可以取代“分库分表”方案

支持分区间并行

单表分区个数最大8192

单机partition支持上限: 8万(推荐不超过3万)


OceanBase分区表

分为一级分区和二级分区

OB现在支持的一级分区类型有:HASH,KEY,LIST,RANGE,RANGE COLUMNS,生成列分区

二级分区相当于在一级分区的基础上,又从第二个维度进行了拆分


MySQL模式:

RANGE分区,NGE COLUMNS 分区,LIST 分区,LIST COLUMNS 分区,HASH 分区,KEY 分区,组合分区

Oracle 模式:

RANGE 分区,LIST 分区,HASH 分区,组合分区


HASH 分区

一级分区


HASH分区需要指定分区键和分区个数,适合于对不能用 Range 分区、List 分区方法的场景。通过对分区键上的Hash函数值来散列记录到不同分区中。通常用于给定分区键的点查询,例如按照用户id来分区。HASH分区通常能消除热点查询。

create table t1 (c1 int, c2 int) partition by hash(c1 + 1) partitions 5

其中partition by hash(c1+1)指定了分区键c1和分区表达式c1 + 1;partitions 5指定了分区数


OB MySQL模式的Hash分区限制和要求:


分区表达式的结果必须是int类型。

不能写向量,例如partition by hash(c1, c2)

KEY 分区

一级分区

KEY分区与HASH分区类似,也是通过对分区个数取模的方式来确定数据属于哪个分区,不同在于:

系统会对Key分区键做一个内部默认的Hash函数后再取模

用户通常没有办法自己通过简单的计算来得知某一行属于哪个分区

测试发现KEY分区所用到的HASH函数不太均匀

create table t1 (c1 varchar(16), c2 int) partition by key(c1) partitions 5

KEY分区不要求是int类型,可以是任意类型

KEY分区不能写表达式(与HASH分区区别)

KEY分区支持向量

KEY分区有一个特殊的语法

create table t1 (c1 int primary key, c2 int) partition by key() partitions 5

KEY分区分区键不写任何column,表示key分区的列是主键

LIST 分区

一级分区

LIST分区是根据枚举类型的值来划分分区的,主要用于枚举类型

LIST分区的限制和要求

分区表达式的结果必须是int类型

不能写向量,例如partition by list(c1, c2)

create table t1 (c1 int, c2 int) partition by list(c1) 
(partition p0 values in (1,2,3), 
partition p1 values in (5, 6),
partition p2 values in (default));

List columns 和 list 的区别是:

list columns分区不要求是int类型,可以是任意类型

list columns分区不能写表达式

list columns分区支持向量

RANGE 分区

一级分区

RANGE分区是按用户指定的表达式范围将每一条记录划分到不同分区

常用场景: 按时间字段进行分区

目前提供对range分区的分区操作功能,能add/drop分区

存在maxvalue的分区的情况,由于add分区现在只能加在最后,所以会添加分区失败

不存在maxvalue的分区的情况,当插入的数据超出当前分区的最大值,则会插入失败。

CREATE TABLE `info_t`(id INT, gmt_create TIMESTAMP, info VARCHAR(20), PRIMARY KEY (gmt_create)) 
PARTITION BY RANGE(UNIX_TIMESTAMP(gmt_create)) 
(PARTITION p0 VALUES LESS THAN (UNIX_TIMESTAMP('2015-01-01 00:00:00')), 
PARTITION p1 VALUES LESS THAN (UNIX_TIMESTAMP('2016-01-01 00:00:00')), 
PARTITION p2 VALUES LESS THAN (UNIX_TIMESTAMP('2017-01-01 00:00:00')));

RANGE COLUMNS 分区

一级分区

RANGE COLUMNS分区与RANGE分区类似,但不同点在于RANGE COLUMNS分区可以按一个或多个分区键向量进行分区,并且每个分区键的类型除了INT类型还可以支持其他类型,比如VARCHAR、DATETIME等


RANGE COLUMNS和RANGE的区别是


1. RANGE COLUMNS分区不要求是int类型,可以是任意类型

2. RANGE COLUMNS分区不能写表达式

3. RANGE COLUMNS分区支持向量

生成列分区  

一级分区

生成列是指这一列是由其他列计算而得

生成列分区是指将生成列作为分区键进行分区,该功能能够更好的满足期望将某些字段进行一定处理后作为分区键的需求(比如提取一个字段的一部分,作为分区键)

CREATE TABLE gc_part_t(t_key varchar(10) PRIMARY KEY, gc_user_id VARCHAR(4) GENERATED 
ALWAYS AS (SUBSTRING(t_key, 1, 4)) VIRTUAL, c3 INT) 
PARTITION BY KEY(gc_user_id) 
PARTITIONS 10;

二级分区

二级分区是指按照两个维度来把数据拆分成分区。最常用的地方就是类似用户账单领域,会按照user_id做HASH分区,按照账单创建时间做RANGE分区

示例:按两个维度划分数据:

CREATE TABLE history_t (user_id INT, 
gmt_create DATETIME, info VARCHAR(20), 
PRIMARY KEY(user_id, gmt_create)) 
PARTITION BY RANGE COLUMNS (gmt_create) 
SUBPARTITION BY HASH(user_id) SUBPARTITIONS 3 
(PARTITION p0 VALUES LESS THAN ('2014-11-11'), 
PARTITION p1 VALUES LESS THAN ('2015-11-11'), 
PARTITION p2 VALUES LESS THAN ('2016-11-11'),
PARTITION p3 VALUES LESS THAN ('2017-11-11')
);



二级分区支持的分区方式

二级分区支持的分区方式


HASH/KEY + RANGE/RANGE_COLUMNS 分区

RANGE/RANGE_COLUMNS + HASH/KEY 分区

LIST/LIST_COLUMNS+ RANGE/RANGE_COLUMNS 分区

RANGE/RANGE_COLUMNS + LIST/LIST_COLUMNS分区

HASH/KEY + LIST/LIST_COLUMNS 分区

LIST/LIST_COLUMNS+HASH/KEY 分区

对于RANGE分区的分区操作add/drop,必须是RANGE分区作为一级分区的方式。所以强烈建议用RANGE + HASH的分区方式,而不是HASH + RANGE。


分区管理

增加分区

伴随数据量增长,range分区需要能够扩展 -> ADD PARTITION


语法: ALTER TABLE ... ADD PARTITION

ALTER TABLE members ADD PARTITION(PARTITION p3 VALUES LESS THAN(2000));

删除分区

对于按时间范围分区的表,有时需要作过期数据清理 -> DROP PARTITION

语法: ALTER TABLE ... DROP PARTITION

ALTER TABLE members DROP PARTITION(P3);

使用限制

只有range分区,可以删除任意一个一级range分区

只能以append方式往后添加分区,也就是说,新加分区的range value总是最大的


分区选择和分区裁剪

表结构

create table t2(c1 int primary key, c2 int, c3 int) partition by hash(c1) partitions 5;

分区选择

explain select * from t1 partition(p4);


分区裁剪

explain select * from t2 where c1 = 5 or c1 = 4;


一级分区裁剪的基本原理-Hash/List 分区

分区裁剪就是根据 where 子句里面的条件并且计算得到分区列的值,然后通过结果判断需要访问哪些分区如果分区函数为表达式,且该表达式作为一个整体出现在等值条件里,也可以做分区裁剪

一级分区裁剪的基本原理-Range分区

通过where子句的分区键的范围跟表定义的分区范围的交集来确定需要访问的分区

对于Range分区,因为考虑到函数单调性,如果分区表达式是一个函数并且查询条件是一个范围,则不支持分区裁剪



二级分区裁剪的基本原理

对于二级分区,先按照一级分区键确定一级需要访问的分区,然后在通过二级分区键确定二级分区需要访问的分区。然后做一个乘积确定二级分区访问的所有物理分区。


分区表的使用建议


业务形态(热点数据打散、历史数据维护便利性、业务SQL的条件形态(分区裁剪)


OB各种分区类型的设置要求


分区键必须是主键的子集


Range分区,最后一个不能是maxvalue


考虑分区裁剪、partition wise join优化


Leader binding\Tablegroup


为了避免写入放大问题,选择表的自定义主键时,不要使用随机生成的值,要尽量有序,比如时序递增的。


分区个数:单机分区上限、单机租户允许创建的最大分区数量上限、单表分区数上限


相关文章
|
1月前
|
SQL 存储 弹性计算
GaussDB SQL调优:建立合适的索引
GaussDB SQL调优:建立合适的索引
12 0
|
7月前
|
SQL 监控
OBCP第四章 SQL调优-SQL执行性能监控
OBCP第四章 SQL调优-SQL执行性能监控
59 0
|
7月前
|
SQL 关系型数据库 MySQL
OBCP第四章 SQL调优-Hint
OBCP第四章 SQL调优-Hint
200 0
|
7月前
|
SQL 索引 OceanBase
OBCP第四章 SQL调优-局部索引与全局索引
OBCP第四章 SQL调优-局部索引与全局索引
79 0
|
9天前
|
SQL XML 前端开发
sql 性能优化基于explain调优(二)
sql 性能优化基于explain调优(二)
17 0
|
3月前
|
SQL 存储 数据库
达梦(DM) SQL调优
【1月更文挑战第2天】达梦(DM) SQL调优
|
5月前
|
SQL 关系型数据库 MySQL
sql处理重复的列,更好理清分组和分区
sql处理重复的列,更好理清分组和分区
46 0
|
5月前
|
SQL 关系型数据库 OLTP
PostgreSQL技术大讲堂 - 第31讲:SQL调优技巧
PostgreSQL从小白到专家,系列技术大讲堂 - 第31讲:SQL调优技巧
573 3
|
7月前
|
SQL 关系型数据库 MySQL
OBCP第四章 SQL调优-索引
OBCP第四章 SQL调优-索引
56 0
|
17天前
|
SQL 人工智能 算法
【SQL server】玩转SQL server数据库:第二章 关系数据库
【SQL server】玩转SQL server数据库:第二章 关系数据库
52 10