Apache Doris (十四) :聚合模型的局限性、模型选择建议及列定义建议

news2024/11/24 3:37:24

目录

1. 聚合模型的局限性

2.数据模型的选择建议

2.1 Aggregate数据模型选择

​​​​​​​​​​​​​​2.2 Unique数据模型选择

​​​​​​​​​​​​​​2.3 Duplicate数据模型选择

​​​​​​​3. 列定义建议


进入正文之前,欢迎订阅专题、对博文点赞、评论、收藏,关注IT贫道,获取高质量博客内容!


1. 聚合模型的局限性

以上Aggregate数据模型和Unique数据模型是聚合模型,Duplicate数据模型不是聚合模型,聚合模型存在一些局限性,这里说的局限性主要体现在select count(*) from table 操作效率和语意正确性两方面,下面我们针对 Aggregate 模型,来介绍下聚合模型的局限性。

在聚合模型中,模型对外展现的,是最终聚合后的数据。也就是说,在Doris内部任何还未聚合的数据(比如说两个不同导入批次的数据),必须通过某种方式,以保证对外展示的一致性。我们举例说明。

假设表结构如下:

 建表语句如下:

CREATE TABLE IF NOT EXISTS example_db.test
(
`user_id` LARGEINT NOT NULL COMMENT "用户id",
`date` DATE NOT NULL COMMENT "数据灌入日期",
`cost` BIGINT SUM COMMENT "用户总消费"
)
AGGREGATE KEY(`user_id`, `date`)
DISTRIBUTED BY HASH(`user_id`) BUCKETS 1
PROPERTIES (
"replication_allocation" = "tag.location.default: 1"
);

向表中分别插入两批次数据,第一批次SQL如下:

insert into example_db.test values 
(10001,"2017-11-20",50),
(10002,"2017-11-21",39);

第二批次SQL如下:

insert into example_db.test values 
(10001,"2017-11-20",1),
(10001,"2017-11-21",5),
(10003,"2017-11-22",22);

可以看到“10001,2017-11-20”这条数据虽然分在了两个批次中,但是由于设置了Aggregate Key 所以是相同数据,进行了聚合。两批次数据插入后,test表中数据如下:

 另外,在聚合列(Value)上,执行与聚合类型不一致的聚合类查询时,要注意语意。比如我们在如上示例中执行如下查询:

mysql> select min(cost) from test;
+-------------+
| min(`cost`) |
+-------------+
|           5 |
+-------------+
1 row in set (0.03 sec)

以上结果得到的是5,而不是1,归根结底就是底层数据进行了合并,是一致性保证的体现。这种一致性的保证,在某些查询中,会极大的降低查询效率。例如,在“select count(*) from table”这种操作中,这种一致性保证就会大幅降低查询效率,原因如下:

在其他数据库中,这类查询都会很快的返回结果,因为在实现上,我们可以通过如“导入时对行进行计数,保存 count 的统计信息”,或者在查询时“仅扫描某一列数据,获得 count 值”的方式,只需很小的开销,即可获得查询结果。但是在 Doris 的聚合模型中,这种查询的开销非常大。

以上案例中,我们执行“select count(*) from test;”正确结果为4,为了得到正确的结果,我们必须同时读取 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; 的语义。

建表语句如下:

CREATE TABLE IF NOT EXISTS example_db.test1
(
`user_id` LARGEINT NOT NULL COMMENT "用户id",
`date` DATE NOT NULL COMMENT "数据灌入日期",
`cost` BIGINT SUM COMMENT "用户总消费",
`count` BIGINT SUM COMMENT "用于计算count"
)
AGGREGATE KEY(`user_id`, `date`)
DISTRIBUTED BY HASH(`user_id`) BUCKETS 1
PROPERTIES (
"replication_allocation" = "tag.location.default: 1"
);

插入如下数据:

insert into test1 values 
(10001,"2017-11-20",50,1),
(10002,"2017-11-21",39,1),
(10001,"2017-11-21",5,1),
(10003,"2017-11-22",22,1);

执行sql语句对比:

# select count(*) from test1; 等价  select sum(count) from test1(效率高);
mysql> select count(*) from test1;
+----------+
| count(*) |
+----------+
|        4 |
+----------+
1 row in set (0.04 sec)

mysql> select count(*) from test1;
+----------+
| count(*) |
+----------+
|        4 |
+----------+
1 row in set (0.03 sec)

此外,聚合模型的局限性注意以下几点:

  1. Unique模型的写时合并没有聚合模型的局限性(效率低下局限),因为写时合并原理是写入数据时已经将数据合并并会对过时数据进行标记删除,在数据查询时不需进行任何数据聚合,在测试环境中,count(*) 查询在Unique模型的写时合并实现上的性能,相比聚合模型有10倍以上的提升。
  2. Duplicate 模型没有聚合模型的这个局限性。因为该模型不涉及聚合语意,在做 count(*) 查询时,任意选择一列查询,即可得到语意正确的结果。
  3. Duplicate、Aggregate、Unique 模型,都会在建表指定 key 列,然而实际上是有所区别的:对于 Duplicate 模型,表的key列,可以认为只是 “排序列”,并非起到唯一标识的作用。而 Aggregate、Unique 模型这种聚合类型的表,key 列是兼顾 “排序列” 和 “唯一标识列”,是真正意义上的“ key 列”。

2.数据模型的选择建议

Doris中数据模型在建表时就已经确定,且无法修改。所以,选择一个合适的数据模型非常重要。如果在建表时没有指定数据模型,doris会根据创建列是否有聚合字段来决定使用什么模型,没有聚合字段默认是Duplicate数据存储模型,根据前缀索引长度决定选择那些列当做key列;如果有聚合key,默认为Aggregate数据存储模型,聚合列之前的列为key列。

​​​​​​​2.1 Aggregate数据模型选择

Aggregate 模型可以通过预聚合,极大地降低聚合查询时所需扫描的数据量和查询的计算量,非常适合有固定模式的报表类查询场景。但是该模型对 count(*) 查询很不友好。同时因为固定了 Value 列上的聚合方式,在进行其他类型的聚合查询时,需要考虑语意正确性。

​​​​​​​​​​​​​​2.2 Unique数据模型选择

Unique模型针对需要唯一主键约束的场景,可以保证主键唯一性约束。但是无法利用ROLLUP等预聚合带来的查询优势。

对于聚合查询有较高性能需求的用户,推荐使用自1.2版本加入的写时合并实现。

Unique 模型仅支持整行更新,如果用户既需要唯一主键约束,又需要更新部分列(例如将多张源表导入到一张 doris 表的情形),则可以考虑使用 Aggregate 模型,同时将非主键列的聚合类型设置为 REPLACE_IF_NOT_NULL。具体的用法可以参考语法手册。

​​​​​​​​​​​​​​2.3 Duplicate数据模型选择

Duplicate 这种数据模型适用于既没有聚合需求,又没有主键唯一性约束的原始数据的存储,适合任意维度的 Ad-hoc 查询。虽然同样无法利用预聚合的特性,但是不受聚合模型的约束,可以发挥列存模型的优势(只读取相关列,而不需要读取所有 Key 列)。

​​​​​​​3. 列定义建议

关于Doris表的类型,可以通过在 mysql-client 中执行 HELP CREATE TABLE; 查看。在定义Doris表中列类型时有如下建议:

  1. AGGREGATE KEY 数据模型Key 列必须在所有 Value 列之前。
  2. 尽量选择整型类型。因为整型类型的计算和查找效率远高于字符串。
  3. 对于不同长度的整型类型的选择原则,遵循够用即可。
  4. 对于 VARCHAR 和 STRING 类型的长度,遵循够用即可。
  5. 表中一行数据所有列总的字节数不能超过100KB。如果数据一行非常大,建议拆分数据进行多表存储。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/709437.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

天津大学计算机考研分析

关注我们的微信公众号 姚哥计算机考研 更多详情欢迎咨询 天津大学(B)考研难度(☆☆☆☆) 天津大学计算机考研主要招生学院在智能与计算学部、佐治亚理工深圳学院、新媒体与传播学院。招生学院较多,目前均已出拟录取…

时间序列分解 | Matlab奇异谱分析SSA做信号去噪、分解

文章目录 效果一览文章概述部分源码参考资料效果一览 文章概述 时间序列分解 | Matlab奇异谱分析SSA做信号去噪、分解 部分源码 %----------------------

HPM6750系列--第四篇 搭建Visual Studio Code开发调试环境

一、目的 在之前的博客《HPM6750系列--第二篇 搭建Ubuntu开发环境》、《HPM6750系列--第三篇 搭建MACOS编译和调试环境》我们介绍了基于命令行的编译调试过程,整个过程稍微有些繁琐可能有些小伙伴不太习惯,那么本篇就介绍一下在Visual Studio Code下的开…

【Linux系统编程】shell的感性理解

文章目录 1. shell是什么?它有什么作用?2. 通过一个故事感性理解shell的运行机制开端发展波澜渐起(正常命令的处理)故事角色与处理过程中各部分的映射走向高潮(非法请求的处理)shell 存在的意义结尾 1. she…

Leetcode-每日一题【142.环形链表Ⅱ】

题目 给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部…

每天一点Python——day45

#第四十五天 #字典元素的特点: #例:字典中的所有元素都是一个key-value对【键值对】,key不允许重复,value可以重复 a{name:张三,name:李四} print(a) #只会输出李四,因为键不允许重复,否则会出现值覆盖的情…

QMenu代码生成器

共4种选项: 文本:输入父对象名,文本即可 文本图标:输入父对象名,文本,图标 文本图标菜单:输入父对象名,子对象名,文本,图标 文本菜单:输入父对象名…

14 | count(*)这么慢,我该怎么办?

一下内容出自《MySQL 实战 45 讲》 14 | count(*)这么慢,我该怎么办? count(*) 的实现方式 不同的 MySQL 引擎中,count(*) 有不同的实现方式。 MyISAM 引擎把一个表的总行数存在了磁盘上,执行 count(*) 的时候会直接返回这个数…

斯坦福大学吴佳俊:通过自然监督编码理解视觉世界

导读 在智源大会的生成模型论坛上,斯坦福大学助理教授吴佳俊带来了精彩的演讲 “通过自然监督编码理解视觉世界”(Understanding the Visual World Through Naturally Supervised Code)。此次演讲从二维图像拓展到三维世界,从人类…

linux高并发网络编程开发(xml json)16_xml和Json相关api及文件解析制作

pdf详细版 01 学习目标 xml xml基础语法和规范C程序中如何使用xml开源库借助开源库,在C程序中生成xml文件已知一个xml文件,如何借助开源库解析xml文件数据 Json json的基础语法和规范C程序中如何使用json开源库 - cjson使用cjson生成json文件已知一个json文件,使用cjson库解析…

列存储、行存储

一、定义 1.1定义 Sybase在2004年左右就推出了列存储的Sybase IQ数据库系统,主要用于在线分析、数据挖掘等查询密集型应用。列存储,缩写为DSM,相对于NSM(N-ary storage model),其主要区别在于: DSM将所有记录中相同字段的数据聚…

【AUTOSAR】BMS开发实际项目讲解(二十三)----电池管理系统高压互锁保护

高压互锁保护 关联的系统需求 TSR-BMS-6101、TSR-BMS-6102、TSR-BMS-6103、TSR-BMS-6104、TSR-BMS-6105、TSR-BMS-6106、TSR-BMS-6107、TSR-BMS-6108、TSR-BMS-6109、TSR-BMS-6110、TSR-BMS-6111; TSR-BMS-6201; TSR-BMS-6301; TSR-BMS-S101、TSR-BMS-S102、TSR-BMS-S103、TS…

AutoSAR系列讲解(入门篇)4.3-BSW的Communication功能

一、架构与术语解释 BSW中以后每一节我都会放上一张模块图,所以就先上图: 由于汽车上一般都使用CAN总线,图中的bus大家可以就当成CAN来看待,如果使用的是LIN或者其他的,也相应的换成其总线看待就行。后续在实践篇中将会…

你需要了解的 50 个 ChatGPT 统计数据和事实

Rest assured that with the ChatGPT statistics you’re about to read, you’ll confirm that the popular chatbot from OpenAI is just the beginning of something bigger. Since its launch in November 2022, ChatGPT has broken unexpected records. For example, it r…

数据结构之串

1.串的基本概念 • 一个串是由n(n≥0)个字符组成的有限序列,记为s“s0s1 ⋯ sn-1”,其 中,s是串名,双引号括起来的字符序列s0s1 ⋯ sn-1是串值。 • 一个字符在串中的位置称为该字符在串中的序号&#xff…

微搭低代码实现表单打印功能

目录 1 引入第三方库2 搭建页面3 实现打印4 实现效果总结 在我们的日常开发场景中,表单打印是一个比较常见的场景,微搭本身不带打印功能,我们需要借助一个第三方的库来实现打印。 1 引入第三方库 在微搭中如果需要引入第三方库的&#xff0…

阿里云免费云服务器领取教程

阿里云推出了免费试用中心,提供超百款免费试用云产品,个人用户与企业用户均可免费试用,云服务器最长免费体验3个月! 一、活动地址 阿里云免费试用中心 二、活动对象 满足以下全部条件的阿里云用户: 1、阿里云注册会…

JS模块化规范及进化史

模块化规范及进化史 按照功能和需求分成各个模块,最后再把所有模块合并在一起。当然现在基于webpack vue/react,模块化开发很重要。某个功能板块单独写成一个模块,然后把模块合在一起,最后把整个页面的功能实现。方便团队管理 小插…

stunnel-加密通道-squid-IP缓存服务器-openssl自签名证书

文章目录 1.安装squid2.管理squid服务3.安装Stunnel服务器端4.安装Stunnel客户端5.在目标使用位置开启代理 1.安装squid yum install squid 2.管理squid服务 systemctl start squid systemctl stop squid systemctl status squid 查看端口 netstat -lntpo | grep 8**** 修改配…

集成增益采样电路误差计算--适用INA214

一、 一般集成电路结构如下: 二、 典型的计算步骤如下: 主要误差来源:采样电阻R-shunt,集成增益运放,ADC误差。 采样电阻误差 误差项包括常温下电阻的精度X1%,电阻的温漂值X2% 误差百分比为:…