杭州网站建设公司排行,网站站群建设进度,ap课程培训哪家机构好,制作网页中的链接怎么弄Doris 的数据模型主要分为 3 类#xff1a;Aggregate、Uniq、Duplicate
Aggregate: Doris 数据模型-Aggregate 模型
Uniq#xff1a;Doris 数据模型-Uniq 模型
Duplicate#xff1a;Doris 数据模型-Duplicate 模型
因为数据模型在建表时就已经确定#xff0c;且无法修改…Doris 的数据模型主要分为 3 类Aggregate、Uniq、Duplicate
Aggregate: Doris 数据模型-Aggregate 模型
UniqDoris 数据模型-Uniq 模型
DuplicateDoris 数据模型-Duplicate 模型
因为数据模型在建表时就已经确定且无法修改。所以选择一个合适的数据模型非常重要。
1Aggregate 模型可以通过预聚合极大地降低聚合查询时所需扫描的数据量和查询的计算量非常适合有固定模式的报表类查询场景。但是该模型对 count(*) 查询很不友好。
同时因为固定了 Value 列上的聚合方式在进行其他类型的聚合查询时需要考虑语意正确性。
2Uniq 模型针对需要唯一主键约束的场景可以保证主键唯一性约束。但是无法利用 ROLLUP 等预聚合带来的查询优势因为本质是 REPLACE没有 SUM 这种聚合方式。
3Duplicate 适合任意维度的 Ad-hoc 查询。虽然同样无法利用预聚合的特性但是不受聚合模型的约束可以发挥列存模型的优势只读取相关列而不需要读取所有 Key 列
聚合模型的局限性
这里我们针对 Aggregate 模型包括 Uniq 模型来介绍下聚合模型的局限性。
在聚合模型中模型对外展现的是最终聚合后的数据。也就是说任何还未聚合的数据比如说两个不同导入批次的数据必须通过某种方式以保证对外展示的一致性。我们举例说明。
假设表结构如下 假设存储引擎中有如下两个已经导入完成的批次的数据
batch 1 batch 2 可以看到用户 10001 分属在两个导入批次中的数据还没有聚合。但是为了保证用户只能查询到如下最终聚合后的数据 在查询引擎中加入了聚合算子来保证数据对外的一致性。
另外在聚合列Value上执行与聚合类型不一致的聚合类查询时要注意语意。比如我们在如上示例中执行如下查询 SELECT MIN(cost) FROM table; 得到的结果是 5而不是 1。
同时这种一致性保证在某些查询中会极大的降低查询效率。
我们以最基本的 count(*) 查询为例 SELECT COUNT(*) FROM table; 在其他数据库中这类查询都会很快的返回结果。因为在实现上我们可以通过如“导入时对行进行计数保存 count 的统计信息”或者在查询时“仅扫描某一列数据获得 count值”的方式只需很小的开销即可获得查询结果。但是在 Doris 的聚合模型中这种查询的开销非常大。
上面的例子select count(*) from table; 的正确结果应该为 4。但如果我们只扫描 user_id 这一列如果加上查询时聚合最终得到的结果是 310001, 10002, 10003。而如果不加查询时聚合则得到的结果是 5两批次一共 5 行数据。
可见这两个结果都是不对的。
为了得到正确的结果我们必须同时读取 user_id 和 date 这两列的数据再加上查询时聚合才能返回 4 这个正确的结果。也就是说在 count(*) 查询中Doris 必须扫描所有的AGGREGATE KEY 列这里就是 user_id 和 date并且聚合后才能得到语意正确的结果。
当聚合列非常多时count(*)查询需要扫描大量的数据。
因此当业务上有频繁的 count(*)查询时我们建议用户通过增加一个值恒为 1 的聚合类型为 SUM 的列来模拟count(*)。如刚才的例子中的表结构我们修改如下 增加一个 count 列并且导入数据中该列值恒为 1。则 select count(*) from table; 的结果等价于 select sum(count) from table;。而后者的查询效率将远高于前者。不过这种方式也有使用限制就是用户需要自行保证不会重复导入 AGGREGATE KEY 列都相同的行。否则select sum(count) from table; 只能表述原始导入的行数而不是 select count(*)from table; 的语义。