Doris–基础–12–Colocation Join
1、介绍
- 旨在为某些 Join 查询提供本地性优化,来减少数据在节点间的传输耗时,加速查询。
1.1、原理
Colocation Join 功能,是将一组拥有相同 CGS(Colocation Group Schema) 的 Table 组成一个 CG(Colocation Group。并保证这些 Table 对应的数据分片会落在同一个 BE 节点上。使得当 CG 内的表进行分桶列上的 Join 操作时,可以通过直接进行本地数据 Join,减少数据在节点间的传输耗时。
1.2、使用限制
- 建表时,两张表的分桶列和数量需要完全一致,并且桶的个数也需要一致
- 两张表的所有分区和副本数需要一致
2、使用方式
2.1、建表
- 建表时, 在 PROPERTIES 中指定属性 “colocate_with” = “group_name”,表示这个表是一个 Colocation Join 表,并且归属于一个指定的 Colocation Group。
- 如果指定的 Group 不存在,则 Doris 会自动创建一个只包含当前这张表的 Group。
- 如果指定的 Group 已存在,则 Doris 会检查当前表是否满足 Colocation Group Schema。
- 如果满足
- 会创建该表,并将该表加入 Group。
- 表会根据已存在的 Group 中的 数据分布规则 创建分片和副本。
- 如果满足
- Group 归属
- 归属于一个 Database
- Group 的名字在一个 Database 内唯一。
- 命名规则
- 在内部存储是 Group 的全名为:dbId_groupName,但用户只感知 groupName。
2.1.1、示例
CREATE TABLE tbl (k1 int, v1 int sum)
DISTRIBUTED BY HASH(k1)
BUCKETS 8
PROPERTIES(
"colocate_with" = "group1"
);
2.2、删表
- 当 Group 中最后一张表彻底删除后,该 Group 也会被自动删除
- 彻底删除:
- 指从回收站中删除。通常,一张表通过 DROP TABLE 命令删除后,会在回收站默认停留一天的时间后,再删除
2.3、查看 Group
2.3.1、查看 Group
SHOW PROC '/colocation_group';
GroupId:
1. 一个 Group 的全集群唯一标识
2. 前半部分为:DB ID
3. 后半部分为:group ID。
GroupName:Group 的全名。
TabletIds:该 Group 包含的 Table 的 id 列表。
BucketsNum:分桶数。
ReplicationNum:副本数。
DistCols:Distribution columns,即分桶列类型。
IsStable:该 Group 是否稳定(稳定的定义,见 Colocation 副本均衡和修复 一节)。
2.3.2、查看一个 Group 的数据分布情况
该命令需要 ADMIN 权限。暂不支持普通用户查看。
SHOW PROC '/colocation_group/13003.13352';
BucketIndex:分桶序列的下标。
BackendIds:分桶中数据分片所在的 BE 节点 id 列表。
2.4、修改表 Colocate Group 属性
2.4.1、对一个已经创建的表,修改其 Colocation Group 属性
ALTER TABLE tbl SET ("colocate_with" = "group2");
SHOW PROC '/colocation_group/' ;
- 如果该表之前 没有指定过 Group,则该命令 检查 Schema,并将该表加入到该 Group(Group 不存在则会创建)。
- 如果该表之前 有指定过 Group,则该命令会 先将该表从原有 Group 中移除,再加入新 Group(Group 不存在则会创建)。
2.4.1、删除一个表的 Colocation 属性
ALTER TABLE tbl SET ("colocate_with" = "");
2.5、其他相关操作
当对一个具有 Colocation 属性的表进行以下操作,Doris 会检查修改是否会违反 Colocation Group Schema,如果违反则会拒绝。
- 增加分区(ADD PARTITION)
- 修改副本数
2.6、演示
- 对 Colocation 表的查询方式和普通表一样,用户无需感知 Colocation 属性。
- 如果 Colocation 表所在的 Group 处于 Unstable 状态,将自动退化为普通 Join。
2.6.1、创建表1:
CREATE TABLE IF NOT EXISTS tbl1 (
`k1` date NOT NULL COMMENT "k1",
`k2` int(11) NOT NULL COMMENT "k2",
`v1` int(11) SUM NOT NULL COMMENT "v1"
) ENGINE=OLAP
AGGREGATE KEY(`k1`, `k2`)
PARTITION BY RANGE(`k1`)
(
PARTITION p1 VALUES LESS THAN ('2023-02-28'),
PARTITION p2 VALUES LESS THAN ('2023-03-31')
)
DISTRIBUTED BY HASH(`k2`) BUCKETS 8
PROPERTIES (
"colocate_with" = "group1"
);
2.6.2、创建表2:
CREATE TABLE tbl2 (
`k1` datetime NOT NULL COMMENT "k1",
`k2` int(11) NOT NULL COMMENT "k2",
`v1` double SUM NOT NULL COMMENT "v1"
) ENGINE=OLAP
AGGREGATE KEY(`k1`, `k2`)
DISTRIBUTED BY HASH(`k2`) BUCKETS 8
PROPERTIES (
"colocate_with" = "group1"
);
2.6.3、查看查询计划
DESC SELECT * FROM tbl1 INNER JOIN tbl2 ON (tbl1.k2 = tbl2.k2);
- 如果 Colocation Join 生效,则 Hash Join 节点会显示 colocate: true。