文章目录
一. 使用衍生维度(derived dimension)
衍生维度用于在有效维度内将维度表上的非主键维度排除掉,并使用维度表的主键(其 实是事实表上相应的外键)来替代它们。Kylin 会在底层记录维度表主键与维度表其他维度 之间的映射关系,以便在查询时能够动态地将维度表的主键“翻译”成这些非主键维度,并 进行实时聚合。
虽然衍生维度具有非常大的吸引力,但这也并不是说所有维度表上的维度都得变成衍生维度,如果从维度表主键到某个维度表维度所需要的聚合工作量非常大,则不建议使用衍生维度。
二. 使用聚合组(Aggregation group)
聚合组(Aggregation Group)是一种强大的剪枝工具。聚合组假设一个 Cube 的所有维度均可以根据业务需求划分成若干组(当然也可以是一个组),由于同一个组内的维度更可能同时被同一个查询用到,因此会表现出更加紧密的内在关联。每个分组的维度集合均是 Cube 所有维度的一个子集,不同的分组各自拥有一套维度集合,它们可能与其他分组有相同的维度,也可能没有相同的维度。每个分组各自独立地根据自身的规则贡献出一批需要被物化的 Cuboid,所有分组贡献的 Cuboid 的并集就成为了当前 Cube 中所有需要物化的 Cuboid 的集合。不同的分组有可能会贡献出相同的 Cuboid,构建引擎会察觉到这点,并且保证每一 个 Cuboid 无论在多少个分组中出现,它都只会被物化一次。
对于每个分组内部的维度,用户可以使用如下三种可选的方式定义,它们之间的关系, 具体如下:
1)强制维度(Mandatory),如果一个维度被定义为强制维度,那么这个分组产生的所 有 Cuboid 中每一个 Cuboid 都会包含该维度。每个分组中都可以有 0 个、1 个或多个强制维 度。如果根据这个分组的业务逻辑,则相关的查询一定会在过滤条件或分组条件中,因此可 以在该分组中把该维度设置为强制维度。(强制维度自己也不能单独出现)
2)层级维度(Hierarchy),每个层级包含两个或更多个维度。假设一个层级中包含 D1, D2…Dn 这 n 个维度,那么在该分组产生的任何 Cuboid 中, 这 n 个维度只会以(),(D1),
(D1,D2)…(D1,D2…Dn)这 n+1 种形式中的一种出现。每个分组中可以有 0 个、1 个 或多个层级,不同的层级之间不应当有共享的维度。如果根据这个分组的业务逻辑,则多个 维度直接存在层级关系,因此可以在该分组中把这些维度设置为层级维度。
3)联合维度(Joint),每个联合中包含两个或更多个维度,如果某些列形成一个联合, 那么在该分组产生的任何 Cuboid 中,这些联合维度要么一起出现,要么都不出现。每个分 组中可以有 0 个或多个联合,但是不同的联合之间不应当有共享的维度(否则它们可以合并 成一个联合)。如果根据这个分组的业务逻辑,多个维度在查询中总是同时出现,则可以在该分组中把这些维度设置为联合维度。
这些操作可以在 Cube Designer 的 Advanced Setting 中的 Aggregation Groups 区域完成。
聚合组的设计非常灵活,甚至可以用来描述一些极端的设计。假设我们的业务需求非常单一,只需要某些特定的 Cuboid,那么可以创建多个聚合组,每个聚合组代表一个 Cuboid。 具体的方法是在聚合组中先包含某个 Cuboid 所需的所有维度,然后把这些维度都设置为强 制维度。这样当前的聚合组就只能产生我们想要的那一个 Cuboid 了。
再比如,有的时候我们的 Cube 中有一些基数非常大的维度,如果不做特殊处理,它就 会和其他的维度进行各种组合,从而产生一大堆包含它的 Cuboid。包含高基数维度的 Cuboid在行数和体积上往往非常庞大,这会导致整个 Cube 的膨胀率变大。如果根据业务需求知道 这个高基数的维度只会与若干个维度(而不是所有维度)同时被查询到,那么就可以通过聚 合组对这个高基数维度做一定的“隔离”。我们把这个高基数的维度放入一个单独的聚合组, 再把所有可能会与这个高基数维度一起被查询到的其他维度也放进来。这样,这个高基数的 维度就被“隔离”在一个聚合组中了,所有不会与它一起被查询到的维度都没有和它一起出现 在任何一个分组中,因此也就不会有多余的 Cuboid 产生。这点也大大减少了包含该高基数 维度的 Cuboid 的数量,可以有效地控制 Cube 的膨胀率。
三. Row Key 优化
Kylin 会把所有的维度按照顺序组合成一个完整的 Rowkey,并且按照这个 Rowkey 升序 排列 Cuboid 中所有的行。
设计良好的 Rowkey 将更有效地完成数据的查询过滤和定位,减少 IO 次数,提高查询 速度,维度在 rowkey 中的次序,对查询性能有显著的影响。
Row key 的设计原则如下:
- 被用作过滤的维度放在前边。
2)基数大的维度放在基数小的维度前边。