[ 
https://issues.apache.org/jira/browse/KYLIN-5309?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17684085#comment-17684085
 ] 

pengfei.zhan edited comment on KYLIN-5309 at 2/4/23 4:29 AM:
-------------------------------------------------------------

h2. 1. 问题背景

在某客户使用 Kylin 的过程中碰到了两种情形可能不适合预计算的场景:

1)维表某些字段的值是动态变化的,而其它的字段不是;

2)表与表之间的关联关系是一对多(或多对多)的关系。

维表字段的数据值是变化的,而历史数据已经被构建到索引中是固化的,那么查询时就可能不是最新值,查询结果可能不准确甚至是完全不对的。要获取准确的查询结果,用户只有通过重刷索引才可以达到目的。如果已经构建好的索引历史数据是几个月甚至是十几年的聚合结果,每次维表变动都需要重刷,那构建资源开销是非常大的,此外,如果数据重刷期间有数据查询的需求,那么用户可能需要经历漫长的等待时间。

对于另外一个场景,多对多的关联关系会在 Kylin 预计算打平表时,表与表 join 
之后的数据量可能出现非常大幅度的增长,由此会引发构建时长会成倍的增加。当用户可使用的计算资源有限 
(事实上用户可使用的资源永远是有限的),这可能是难以令人接受的。

针对这两个场景,Kylin5 引入两个新特性来解决这两类问题。
h2. 2. 解决方案

针对维表某些字段的数据值随时间动态变化这一特性,在项目级别引入一个屏蔽设置的概念,它可以精细化管理到列级别,后面简称“屏蔽列”。这是另一种形式的不预计算。被屏蔽的列被设计成不预计算的,但如果用户在创建聚合组或者明细索引时仍将这些列定义成为维度,构建索引还是会使用这些维度、度量去构建索引。当这些屏蔽列被用户查询时,查询的结果可能是不准确的。

针对表与表之间的对多关联关系,在模型表的关联关系上定义一个新的属性 flattenable 来表示该维表是否预计算。如果该属性的值为 flatten 、空 或 
null,则表示该维表可以预计算;如果该属性值为 
normalized,则表示该维表不参与预计算。维表不参加预计算时,那么不会参与到打平表,索引因此也不会与这些维表之间存在直接联系。join 
的维表不参与预计算后面简称为“不预计算关联关系”。

以上两个解决方案可以看作是两种形式的不预计算,那么在不预计算的情况下如何保证查询可查呢?在预计算和实时查询之间寻找一个折中,借助于 Kylin 
的衍生维度查询来实现,也就是使用外键索引和快照关联后再计算得到最终的查询结果。
h3. 2.1 一些重要的概念

这边先介绍一些 Kylin5 相关的重要概念方便理解接下来的设计
 - 索引,对应于 Kyin5 版本之前的 Cube,分为聚合索引和明细索引。
 - 聚合索引,用来回答带聚合的查询。
 - 明细索引,类似于关系型数据库中的表,但 kylin 明细索引的数据可能来源于多张表 join 后的结果。
 - 多对多、一对多,与关系型数据库中的概念一致。
 - 可计算列,可以被预计算的表达式,不能含聚合函数。
 - 可计算列的显式查询,查询的 SQL 语句中直接使用可计算列对应的列名。
 - 可计算列的隐式查询,查询的 SQL 语句中使用可计算列的表达式。
 - 预计算,将查询需要检索的结果预先计算好,查询时能有效减少表与表之间的 join、聚合、分组等操作,能极大的提升查询性能。
 - 平表,表与表之间按照关联键 join 之后的一个结果集,这个结果集只包含了所有维度或者度量引用到的列。
 - 实时计算,传统的关系型数据库都是实时计算的,join、聚合、分组等耗时的操作都是在查询时实时计算。
 - 快照,kylin 为模型使用的维表创建的数据镜像。快照可在索引构建时自动生成,也可以开启配置后用户自主管理。
 - 带外键的索引,如果索引的维度中包含了外键列,那么这个索引就是带外键的索引。
 - 衍生维度,kylin5 的衍生维度与之前的版本不一样。在 Kylin5 中,如果被 join 
维表上的列没有被定义成维度,但在查询时使用带外键的索引与快照关联起来可以被查询到,那么它就是一个衍生维度。

h2. 3. 详细设计

解决方案中提到了两种形式的不预计算,屏蔽列和不预计算关联关系,接下来分别讲解。

h3. 3.1 屏蔽列

先以一个简单的例子引入屏蔽列的设计。假设用户的原始数据包括一张事实表和一张维表,如下图所示。
 !5309-1.png! 

与此同时,不妨假设所有的列都被维度或者度量引用到,并且某个业务需要构建如下的索引和快照 (FlatTable 是构建过程中生成的平表)。
 !5309-2.png! 

由于业务变动,维表上部分列的数据发生了变化,Kylin 会重新构建快照如下图所示。
 !5309-3.png! 

如果此时索引不重刷,那么索引中的数据结果对于用户来说就已经不正确。屏蔽列这个方案如何做到在不重刷索引的情况下,也能得到合理的结果呢?对应于上图,可以将 c5 
和 c7 设置为屏蔽列不再构建到索引中,当维表的数据发生变化时,只需要重刷维表即可,如下图所示。
 !5309-4.png! 

接下来就元数据变动、表重载、模型设计、查询以及构建分别介绍这个方案实现的一些细节。

h4. 3.1.1 元数据变动
- 用户需要在项目设置中开启屏蔽设置才能看到该功能,对应配置项 `kylin.metadata.table-exclusion-enabled`。
- 屏蔽列信息记录在表的扩展描述性信息 `TableExtDesc` 中,为了使用上的便利,允许屏蔽整张表,因此设计表的屏蔽标志和屏蔽列两个属性。
    - 如果整个表被屏蔽,表的属性 `excluded=true`,`excludedColumns=[]`;
    - 如果只有部分列被屏蔽,表的属性 `excluded=false`,`excludedColumns=[a, b, c]`

h4. 3.1.2 重载表
“屏蔽表(列)” 的信息存储决定了它与重载表操作密不可分。具体来说:

- 如果列的类型发生变化,屏蔽设置在重载表的时候不发生变化;
- 如果整表被屏蔽,当重载表发现需要添加一个新的列的时候,默认新加入的列会被自动当作屏蔽列;
- 如果重载表要删除的列是最后一个没有被屏蔽的列,重载表删除该列的时候,会将整表屏蔽;
- 其他情况比较简单,无需赘述。

h4. 3.1.3 模型设计
模型设计既包括定义模型的事实表、维表、关联关系,也包括定义可计算列、维度、度量,更广义来说应该还包括索引。

- 对事实表来说,“屏蔽表(列)” 无效,会传递到可计算列、维度、度量。
- 对维表来说,可计算列可以定义,但是含有屏蔽列的可计算列,不会被复用;维度和度量均可以定义。
- 对于关联关系,主要是雪花模型中, A join B(on a1 = b1) and B join C (on b2 = c2) 时,b2 
不能是屏蔽列,否则断链。
- 屏蔽列关联的可计算列和度量如果是命中索引,可能导致数据不对 
(可计算列的设计表明了需要预计算,屏蔽列的设计表明了不要预计算,本身就互不相容,所以不要定义屏蔽列相关的可计算列)。
- 设计索引的时候,需要把对应的外键定义为维度,否则查询的时候无法衍生查询 (非常重要,Kylin 的衍生查询必须是索引中有外键)。

h4. 3.1.4 查询
考虑到用户可能定义了屏蔽列相关的维度和度量并且构建好了索引。

- 开启屏蔽列,与屏蔽列相关的可计算列隐式查询时不会被替换。
- 开启屏蔽列,与屏蔽列相关的可计算列显式查询无法被反解析成表达式,查询会下压 (limitation)。
- 开启屏蔽列,并设置 `kylin.query.snapshot-preferred-for-table-exclusion=true` 
那么会优先选择外键索引+快照响应查询;设置为 false 会优先考虑索引回答。
- 开启屏蔽列,并设置 `kylin.metadata.only-reuse-user-defined-computed-column=true` 那么以 
`CC_AUTO` 开头的可计算列无法在索引匹配的流程中替换。
- 关闭屏蔽列,配置`kylin.query.snapshot-preferred-for-table-exclusion` 无任何作用,优先考虑索引回答。

粗略看下 NDataflowCapabilityChecker 如何使用屏蔽列与多对多相关逻辑。查询代码逻辑中会在创建 `AggIndexMatcher` 与 
`TableIndexMatcher` 前创建两个 Checker 类,并且将它们作为构造参数传入到 `IndexMatcher` 
中。索引匹配时,`ColExcludedChecker` 用于检查屏蔽列,`AntiFlatChecker` 用于检查维表不预计算关联关系。
 !5309-5.png! 

除了索引匹配过程中的检查外,另外需要考虑屏蔽列和维表不预计算关联关系的地方包括:

- 查询语句转换阶段 `ConvertToComputedColumn` 对可计算列在 `SqlNode` 层的转换;
- OLAPContext 切分时 `ComputedColumnRewriter` 对可计算列在 `RelNode` 层的替换。

h4. 3.1.5 构建

构建这边不做限制,允许构建带有屏蔽列的索引。

h3. 不与计算关联关系

以一个简单的例子引入不预计算关联关系。假设用户的原始数据包括一张事实表和一张维表,如下图所示。
 !5309-6.png! 

在构建索引之前需要先生成如下的 FlatTable 。
 !5309-7.png! 

假定所有的列都被维度或者度量引用到,由于事实表和维表之间的多对多关联关系,导致平表的数据出现了很明显的膨胀,在这个例子中,从原来的 37 (3 * 4 + 5 
* 5) 个单元格变成 56 (7 * 
8)个单元格。这样就导致构建的时候需要使用更多的计算资源,相应地,构建时间也会更长。一个很明显的结论是,如果给基于这种事实表构建了索引,那么查询的时候是不可以再关联快照的,否则查询结果就完全不对,因此多对多场景一旦选择了预计算,那么查询时将禁止关联快照。

如果我们想构建时避免数据膨胀问题,那构建索引的过程中,维表不再参与到平表的计算,索引只包含了事实表相关的数据,如下图所示。相应地,查询的时候就必须关联快照查询的到最终的查询结果。
 !5309-8.png! 

相比于屏蔽列,不预计算关联g更为严格,它在维度、度量、可计算列定义以及索引构建时就做了强制性的限制,接下来的部分会介绍这些变动。

h4. 3.2.1 元数据变动

在模型表的关联关系上定义一个新的属性 flattenable 来表示该维表是否预计算。

- 如果该属性的值为 flatten 、空 或 null,则表示该维表可以预计算;
- 如果该属性值为 normalized,则表示该维表不参与预计算。

h4. 3.2.2 模型设计

- 如果维表不预计算关联关系,那么维表上的任何列不能参与可计算列、维度、度量的定义。
- 变更模型某维表的关联关系为不预计算时,检测到的任何可计算列、维度、度量、索引与该维表有关系,用户要么放弃变更,要么接受删除检测的结果。
- 变更模型某维表的关联关系为预计算时,整个流程正常。
- 如果变更了模型的关联关系,比如从多对一变更到多对多,那么用户需要重刷索引来保证最终查询结果的准确。
- 设计聚合索引或者明细索引的时候一定要将关联的外键加入到索引中。
- 雪花模型时,保证关联关系不出现断链的情形。例如:A join B && B join C,B 如果不预计算,那么即使 C 
设定为预计算也会被推断为不预计算,此时 B 的这种设定就称为预计算断链了。

h4. 3.2.3 查询
- 如果表的关联关系是对多且不预计算,那么一定是外键索引+快照联合查询得到对应的结果。
- 如果表的关联关系是对多且预计算,那么一定禁止衍生维度查询,查询不到就下压查询。
- 如果表的关联关系是对一且不预计算 (不建议使用,不禁止使用,设计的初衷不是为了解决这种场景),查询不一定需要和快照联合查询。
- 如果表的关联关系是对一且预计算,查询不一定需要快照联合查询。

h4. 3.2.4 构建

构建的时候,不预计算关联关系的维表一定不会参与到打平表当中。

h4. 3.2.5 与屏蔽列的比较

如果一张维表被设定为不预计算,那么不管该维表上的列有没有屏蔽,都不会参与到打平表中,也就不会被构建到索引中。也就是说维表不预计算关联关系会无视屏蔽列的设置。

所以最佳的实践是不要将两个场景混入同一个项目中进行索引的管理,避免由此产生的一些理解上的困难。

h2. 4. 方案解决不了什么问题
- 屏蔽列与可计算列的矛盾
{code:sql}
-- 举个例子:屏蔽列(t.a),模型要定义可计算列 cc1 = t.a + t.b
{code}

- 暂时无法解决可计算列的显式查询问题
{code:sql}
-- 举个例子:屏蔽列(t.a, t.b),定义可计算列 cc1 = t.a + t.b,
-- 聚合索引 index1=[f.c1, t.a, t.b, count(*)]
-- 以下 SQL 无法命中聚合索引 index1
select f.c1, cc1 from f join t on f.id = t.id group by f.c1, cc1
-- 以下  SQL 可以命中聚合索引 index1
select f.c1, t.a + t.b from f join t on f.id = t.id group by f.c1, t.a + t.b
{code}

- 屏蔽列的度量无法查询的问题
{code:sql}
-- 举个例子:度量 sum(t.c3) 这个度量在 t.c3 是屏蔽列的时候无法预计算的
select f.c1, sum(t.c3) from f join t on f.id = t.id group by f.c1
{code}

- 维表不预计算关联关系时,涉及维表上的度量以及可计算列的查询都必须下压
- 使用快照与外键索引的联合必然损失性能,无法做到与直接命中单个索引同样的性能

 


was (Author: JIRAUSER294653):
h2. 1. 问题背景

在某客户使用 Kylin 的过程中碰到了两种情形可能不适合预计算的场景:

1)维表某些字段的值是动态变化的,而其它的字段不是;

2)表与表之间的关联关系是一对多(或多对多)的关系。

维表字段的数据值是变化的,而历史数据已经被构建到索引中是固化的,那么查询时就可能不是最新值,查询结果可能不准确甚至是完全不对的。要获取准确的查询结果,用户只有通过重刷索引才可以达到目的。如果已经构建好的索引历史数据是几个月甚至是十几年的聚合结果,每次维表变动都需要重刷,那构建资源开销是非常大的,此外,如果数据重刷期间有数据查询的需求,那么用户可能需要经历漫长的等待时间。

对于另外一个场景,多对多的关联关系会在 Kylin 预计算打平表时,表与表 join 
之后的数据量可能出现非常大幅度的增长,由此会引发构建时长会成倍的增加。当用户可使用的计算资源有限 
(事实上用户可使用的资源永远是有限的),这可能是难以令人接受的。

针对这两个场景,Kylin5 引入两个新特性来解决这两类问题。
h2. 2. 解决方案

针对维表某些字段的数据值随时间动态变化这一特性,在项目级别引入一个屏蔽设置的概念,它可以精细化管理到列级别,后面简称“屏蔽列”。这是另一种形式的不预计算。被屏蔽的列被设计成不预计算的,但如果用户在创建聚合组或者明细索引时仍将这些列定义成为维度,构建索引还是会使用这些维度、度量去构建索引。当这些屏蔽列被用户查询时,查询的结果可能是不准确的。

针对表与表之间的对多关联关系,在模型表的关联关系上定义一个新的属性 flattenable 来表示该维表是否预计算。如果该属性的值为 flatten 、空 或 
null,则表示该维表可以预计算;如果该属性值为 
normalized,则表示该维表不参与预计算。维表不参加预计算时,那么不会参与到打平表,索引因此也不会与这些维表之间存在直接联系。join 
的维表不参与预计算后面简称为“不预计算关联关系”。

以上两个解决方案可以看作是两种形式的不预计算,那么在不预计算的情况下如何保证查询可查呢?在预计算和实时查询之间寻找一个折中,借助于 Kylin 
的衍生维度查询来实现,也就是使用外键索引和快照关联后再计算得到最终的查询结果。
h3. 2.1 一些重要的概念

这边先介绍一些 Kylin5 相关的重要概念方便理解接下来的设计
 - 索引,对应于 Kyin5 版本之前的 Cube,分为聚合索引和明细索引。
 - 聚合索引,用来回答带聚合的查询。
 - 明细索引,类似于关系型数据库中的表,但 kylin 明细索引的数据可能来源于多张表 join 后的结果。
 - 多对多、一对多,与关系型数据库中的概念一致。
 - 可计算列,可以被预计算的表达式,不能含聚合函数。
 - 可计算列的显式查询,查询的 SQL 语句中直接使用可计算列对应的列名。
 - 可计算列的隐式查询,查询的 SQL 语句中使用可计算列的表达式。
 - 预计算,将查询需要检索的结果预先计算好,查询时能有效减少表与表之间的 join、聚合、分组等操作,能极大的提升查询性能。
 - 平表,表与表之间按照关联键 join 之后的一个结果集,这个结果集只包含了所有维度或者度量引用到的列。
 - 实时计算,传统的关系型数据库都是实时计算的,join、聚合、分组等耗时的操作都是在查询时实时计算。
 - 快照,kylin 为模型使用的维表创建的数据镜像。快照可在索引构建时自动生成,也可以开启配置后用户自主管理。
 - 带外键的索引,如果索引的维度中包含了外键列,那么这个索引就是带外键的索引。
 - 衍生维度,kylin5 的衍生维度与之前的版本不一样。在 Kylin5 中,如果被 join 
维表上的列没有被定义成维度,但在查询时使用带外键的索引与快照关联起来可以被查询到,那么它就是一个衍生维度。

h2. 3. 详细设计

解决方案中提到了两种形式的不预计算,屏蔽列和不预计算关联关系,接下来分别讲解。

h3. 3.1 屏蔽列

先以一个简单的例子引入屏蔽列的设计。假设用户的原始数据包括一张事实表和一张维表,如下图所示。
 !5309-1.png! 

与此同时,不妨假设所有的列都被维度或者度量引用到,并且某个业务需要构建如下的索引和快照 (FlatTable 是构建过程中生成的平表)。
 !5309-2.png! 

由于业务变动,维表上部分列的数据发生了变化,Kylin 会重新构建快照如下图所示。
 !5309-3.png! 

如果此时索引不重刷,那么索引中的数据结果对于用户来说就已经不正确。屏蔽列这个方案如何做到在不重刷索引的情况下,也能得到合理的结果呢?对应于上图,可以将 c5 
和 c7 设置为屏蔽列不再构建到索引中,当维表的数据发生变化时,只需要重刷维表即可,如下图所示。
 !5309-4.png! 

接下来就元数据变动、表重载、模型设计、查询以及构建分别介绍这个方案实现的一些细节。

h4. 3.1.1 元数据变动
- 用户需要在项目设置中开启屏蔽设置才能看到该功能,对应配置项 `kylin.metadata.table-exclusion-enabled`。
- 屏蔽列信息记录在表的扩展描述性信息 `TableExtDesc` 中,为了使用上的便利,允许屏蔽整张表,因此设计表的屏蔽标志和屏蔽列两个属性。
    - 如果整个表被屏蔽,表的属性 `excluded=true`,`excludedColumns=[]`;
    - 如果只有部分列被屏蔽,表的属性 `excluded=false`,`excludedColumns=[a, b, c]`

h4. 3.1.2 重载表
“屏蔽表(列)” 的信息存储决定了它与重载表操作密不可分。具体来说:

- 如果列的类型发生变化,屏蔽设置在重载表的时候不发生变化;
- 如果整表被屏蔽,当重载表发现需要添加一个新的列的时候,默认新加入的列会被自动当作屏蔽列;
- 如果重载表要删除的列是最后一个没有被屏蔽的列,重载表删除该列的时候,会将整表屏蔽;
- 其他情况比较简单,无需赘述。

h4. 3.1.3 模型设计
模型设计既包括定义模型的事实表、维表、关联关系,也包括定义可计算列、维度、度量,更广义来说应该还包括索引。

- 对事实表来说,“屏蔽表(列)” 无效,会传递到可计算列、维度、度量。
- 对维表来说,可计算列可以定义,但是含有屏蔽列的可计算列,不会被复用;维度和度量均可以定义。
- 对于关联关系,主要是雪花模型中, A join B(on a1 = b1) and B join C (on b2 = c2) 时,b2 
不能是屏蔽列,否则断链。
- 屏蔽列关联的可计算列和度量如果是命中索引,可能导致数据不对 
(可计算列的设计表明了需要预计算,屏蔽列的设计表明了不要预计算,本身就互不相容,所以不要定义屏蔽列相关的可计算列)。
- 设计索引的时候,需要把对应的外键定义为维度,否则查询的时候无法衍生查询 (非常重要,Kylin 的衍生查询必须是索引中有外键)。

h4. 3.1.4 查询
考虑到用户可能定义了屏蔽列相关的维度和度量并且构建好了索引。

- 开启屏蔽列,与屏蔽列相关的可计算列隐式查询时不会被替换。
- 开启屏蔽列,与屏蔽列相关的可计算列显式查询无法被反解析成表达式,查询会下压 (limitation)。
- 开启屏蔽列,并设置 `kylin.query.snapshot-preferred-for-table-exclusion=true` 
那么会优先选择外键索引+快照响应查询;设置为 false 会优先考虑索引回答。
- 开启屏蔽列,并设置 `kylin.metadata.only-reuse-user-defined-computed-column=true` 那么以 
`CC_AUTO` 开头的可计算列无法在索引匹配的流程中替换。
- 关闭屏蔽列,配置`kylin.query.snapshot-preferred-for-table-exclusion` 无任何作用,优先考虑索引回答。

粗略看下 NDataflowCapabilityChecker 如何使用屏蔽列与多对多相关逻辑。查询代码逻辑中会在创建 `AggIndexMatcher` 与 
`TableIndexMatcher` 前创建两个 Checker 类,并且将它们作为构造参数传入到 `IndexMatcher` 
中。索引匹配时,`ColExcludedChecker` 用于检查屏蔽列,`AntiFlatChecker` 用于检查维表不预计算关联关系。
 !5309-5.png! 

除了索引匹配过程中的检查外,另外需要考虑屏蔽列和维表不预计算关联关系的地方包括:

- 查询语句转换阶段 `ConvertToComputedColumn` 对可计算列在 `SqlNode` 层的转换;
- OLAPContext 切分时 `ComputedColumnRewriter` 对可计算列在 `RelNode` 层的替换。

h4. 3.1.5 构建

构建这边不做限制,允许构建带有屏蔽列的索引。

h3. 不与计算关联关系

以一个简单的例子引入不预计算关联关系。假设用户的原始数据包括一张事实表和一张维表,如下图所示。
 !5309-6.png! 

在构建索引之前需要先生成如下的 FlatTable 。
 !5309-7.png! 

假定所有的列都被维度或者度量引用到,由于事实表和维表之间的多对多关联关系,导致平表的数据出现了很明显的膨胀,在这个例子中,从原来的 37 (3 * 4 + 5 
* 5) 个单元格变成 56 (7 * 
8)个单元格。这样就导致构建的时候需要使用更多的计算资源,相应地,构建时间也会更长。一个很明显的结论是,如果给基于这种事实表构建了索引,那么查询的时候是不可以再关联快照的,否则查询结果就完全不对,因此多对多场景一旦选择了预计算,那么查询时将禁止关联快照。

如果我们想构建时避免数据膨胀问题,那构建索引的过程中,维表不再参与到平表的计算,索引只包含了事实表相关的数据,如下图所示。相应地,查询的时候就必须关联快照查询的到最终的查询结果。
 !5309-8.png! 

相比于屏蔽列,不预计算关联g更为严格,它在维度、度量、可计算列定义以及索引构建时就做了强制性的限制,接下来的部分会介绍这些变动。

h4. 3.2.1 元数据变动

在模型表的关联关系上定义一个新的属性 flattenable 来表示该维表是否预计算。

- 如果该属性的值为 flatten 、空 或 null,则表示该维表可以预计算;
- 如果该属性值为 normalized,则表示该维表不参与预计算。

h4. 3.2.2 模型设计

- 如果维表不预计算关联关系,那么维表上的任何列不能参与可计算列、维度、度量的定义。
- 变更模型某维表的关联关系为不预计算时,检测到的任何可计算列、维度、度量、索引与该维表有关系,用户要么放弃变更,要么接受删除检测的结果。
- 变更模型某维表的关联关系为预计算时,整个流程正常。
- 如果变更了模型的关联关系,比如从多对一变更到多对多,那么用户需要重刷索引来保证最终查询结果的准确。
- 设计聚合索引或者明细索引的时候一定要将关联的外键加入到索引中。
- 雪花模型时,保证关联关系不出现断链的情形。例如:A join B && B join C,B 如果不预计算,那么即使 C 
设定为预计算也会被推断为不预计算,此时 B 的这种设定就称为预计算断链了。

h4. 3.2.3 查询
- 如果表的关联关系是对多且不预计算,那么一定是外键索引+快照联合查询得到对应的结果。
- 如果表的关联关系是对多且预计算,那么一定禁止衍生维度查询,查询不到就下压查询。
- 如果表的关联关系是对一且不预计算 (不建议使用,不禁止使用,设计的初衷不是为了解决这种场景),查询不一定需要和快照联合查询。
- 如果表的关联关系是对一且预计算,查询不一定需要快照联合查询。

h4. 3.2.4 构建

构建的时候,不预计算关联关系的维表一定不会参与到打平表当中。

h4. 3.2.5 与屏蔽列的比较

如果一张维表被设定为不预计算,那么不管该维表上的列有没有屏蔽,都不会参与到打平表中,也就不会被构建到索引中。也就是说维表不预计算关联关系会无视屏蔽列的设置。

所以最佳的实践是不要将两个场景混入同一个项目中进行索引的管理,避免由此产生的一些理解上的困难。

h2. 4. 方案解决不了什么问题
- 屏蔽列与可计算列的矛盾

{code:sql}
-- 举个例子:屏蔽列(t.a),模型要定义可计算列 cc1 = t.a + t.b
{code}

- 暂时无法解决可计算列的显式查询问题
{code:sql}
-- 举个例子:屏蔽列(t.a, t.b),定义可计算列 cc1 = t.a + t.b,
-- 聚合索引 index1=[f.c1, t.a, t.b, count(*)]
-- 以下 SQL 无法命中聚合索引 index1
select f.c1, cc1 from f join t on f.id = t.id group by f.c1, cc1
-- 以下  SQL 可以命中聚合索引 index1
select f.c1, t.a + t.b from f join t on f.id = t.id group by f.c1, t.a + t.b
{code}

- 屏蔽列的度量无法查询的问题
{code:sql}
-- 举个例子:度量 sum(t.c3) 这个度量在 t.c3 是屏蔽列的时候无法预计算的
select f.c1, sum(t.c3) from f join t on f.id = t.id group by f.c1
{code}

- 维表不预计算关联关系时,涉及维表上的度量以及可计算列的查询都必须下压
- 使用快照与外键索引的联合必然损失性能,无法做到与直接命中单个索引同样的性能

 

> Propose more flexible runtime join scenarios for Kylin
> ------------------------------------------------------
>
>                 Key: KYLIN-5309
>                 URL: https://issues.apache.org/jira/browse/KYLIN-5309
>             Project: Kylin
>          Issue Type: New Feature
>          Components: Metadata, Query Engine
>    Affects Versions: 5.0-alpha
>            Reporter: pengfei.zhan
>            Assignee: pengfei.zhan
>            Priority: Major
>             Fix For: 5.0-alpha
>
>         Attachments: 5309-1.png, 5309-2.png, 5309-3.png, 5309-4.png, 
> 5309-5.png, 5309-6.png, 5309-7.png, 5309-8.png
>
>
> At present, the kylin5 already provides a runtime join scenario: 
> non-pre-computation which can be defined when creating a model. Usually, 
> non-pre-computation is used for the scenario of many-to-many to avoid data 
> blowing up dramatically when building the flat table.
> This issue will propose one more flexible runtime join scenario for kylin5. 
> This feature is the excluded table.  More information will be introduced by 
> the Chinese document in the following comments.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to