Apache Doris (二十二) :Doris Rollup物化索引作用及使用注意点

news2024/11/16 7:54:25

目录

1. Rollup 物化索引作用

1.1 改变索引

1.2 聚合数据

​​​​​​​2. Rollup物化索引注意点


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

宝子们点赞、收藏不迷路!抓紧订阅专题!


1. Rollup 物化索引作用

在Doris里Rollup 作为一份聚合物化视图,其在查询中可以起到两个作用:改变索引和聚合数据。

​​​​​​​1.1 改变索引

改变索引主要说的是可以调整前缀索引,因为建表时已经指定了列顺序,所以一个表只有一种前缀索引。这对于使用其他不能命中前缀索引的列作为条件进行的查询来说,效率上可能无法满足需求。因此,我们可以通过创建 ROLLUP 来人为的调整列顺序,以获得更好的查询效率。

 Doris 的前缀索引,即 Doris 会把 Base/Rollup 表中的前 36 个字节(有 varchar 类型则可能导致前缀索引不满 36 个字节,varchar 会截断前缀索引,并且最多使用 varchar 的 20 个字节)在底层存储引擎单独生成一份排序的稀疏索引数据(数据也是排序的,用索引定位,然后在数据中做二分查找),然后在查询的时候会根据查询中的条件来匹配每个 Base/Rollup 的前缀索引,并且选择出匹配前缀索引最长的一个 Base/Rollup。

 

如上图,取查询中 where 以及 on 上下推到 ScanNode 的条件,从前缀索引的第一列开始匹配,检查条件中是否有这些列,有则累计匹配的长度,直到匹配不上或者36字节结束(varchar类型的列只能匹配20个字节,并且会匹配不足36个字节截断前缀索引),然后选择出匹配长度最长的一个 Base/Rollup,下面举例说明,创建了一张Base表以及四张rollup:

创建表 rollup_test1 ,表结构如下:

创建表SQL语句如下:

CREATE TABLE IF NOT EXISTS example_db.rollup_test1
(
`k1` TINYINT,
`k2` SMALLINT,
`k3` INT,
`k4` BIGINT,
`k5` DECIMAL(9,3),
`k6` CHAR(5),
`k7` DATE,
`k8` DATETIME,
`k9` VARCHAR(20),
`k10` DOUBLE MAX,
`k11` FLOAT SUM
)
AGGREGATE KEY(`k1`,`k2`,`k3`,`k4`,`k5`,`k6`,`k7`,`k8`,`k9`)
DISTRIBUTED BY HASH(`k1`) BUCKETS 1
PROPERTIES (
"replication_allocation" = "tag.location.default: 1"
);

向以上表中插入如下数据(注意:不插入数据,后续创建的物化索引不能被命中):

insert into example_db.rollup_test1 values 
(1,2,3,4,1.0,'a',"2023-03-01","2023-03-01 08:00:00","aaa",1.0,1.0),
(5,6,7,8,2.0,'b',"2023-03-02","2023-03-02 08:00:00","bbb",2.0,2.0);

基于rollup_test1表创建四张rollup物化索引表,如下:

#创建 rollup_index1
mysql> ALTER TABLE example_db.rollup_test1 ADD ROLLUP rollup_index1(k9,k1,k2,k3,k4,k5,k6,k7,k8,k10,k11);
Query OK, 0 rows affected (0.05 sec)

#创建rollup_index2
mysql> ALTER TABLE example_db.rollup_test1 ADD ROLLUP rollup_index2(k9,k2,k1,k3,k4,k5,k6,k7,k8,k10,k11);
Query OK, 0 rows affected (0.02 sec)

#创建rollup_index3
mysql> ALTER TABLE example_db.rollup_test1 ADD ROLLUP rollup_index3(k4,k5,k6,k1,k2,k3,k7,k8,k9,k10,k11);
Query OK, 0 rows affected (0.03 sec)

#创建rollup_index4
mysql> ALTER TABLE example_db.rollup_test1 ADD ROLLUP rollup_index4(k4,k6,k5,k1,k2,k3,k7,k8,k9,k10,k11);
Query OK, 0 rows affected (0.02 sec)

desc table all; 查看表rollup_test1 表物化索引信息:

 

Doris中默认将一行数据的前36个字节作为这行数据的前缀索引,但是当遇到VARCHAR类型时,前缀索引会直接截断,以上Base表和rollup物化索引表的前缀索引分别为(TINYINT-1字节、SMALLINT-2字节、INT-4字节、BIGINT-8字节、DECIMAL-16字节、CHAR-1字节、DATETIME-8字节):

rollup_test1(Base表)(k1 ,k2, k3, k4, k5, k6, k7)

rollup_index1(k9)

rollup_index2(k9)

rollup_index3(k4, k5, k6, k1, k2, k3, k7)

rollup_index4(k4, k6, k5, k1, k2, k3, k7)

 

能用的上前缀索引的列上的条件需要是 = < > <= >= in between 这些并且这些条件是并列的且关系使用 and 连接,对于or、!= 等这些不能命中,命中规则是匹配最长的前缀索引。

执行以下查询,查看对应的前缀索引命中情况:

# select * from rollup_test1 where k1 =1 AND k2>3;此语句有k1以及k2上的条件,只有rollup_test1第一列含有条件里的k1,所以匹配最长的前缀索引即rollup_test1,验证如下:
mysql> explain select * from rollup_test1 where k1 =1 AND k2>3;
...
TABLE: default_cluster:example_db.rollup_test1(rollup_test1)
...

# SELECT * FROM rollup_test1 WHERE k4 = 1 AND k5 > 3;此语句有k4以及k5的条件,匹配前缀最长索引,可以匹配到rollup_index3,验证如下:
mysql> explain SELECT * FROM rollup_test1 WHERE k4 = 1 AND k5 > 3;
...
TABLE: default_cluster:example_db.rollup_test1(rollup_index3)
...

下面我们尝试匹配含有varchar列上的条件,执行如下SQL:

mysql> explain select * from rollup_test1 where k9 in ("xxx","yyy") and k1=10;
...
TABLE: default_cluster:example_db.rollup_test1(rollup_index1)
...

有 k9 以及 k1 两个条件,rollup_index1 以及 rollup_index2 的第一列都含有 k9,按理说这里选择这两个 rollup 都可以命中前缀索引并且效果是一样的随机选择一个即可(因为这里 varchar 刚好20个字节,前缀索引不足36个字节被截断),但是当前策略这里还会继续匹配 k1,因为 rollup_index1 的第二列为 k1,所以选择了 rollup_index1,其实后面的 k1 条件并不会起到加速的作用。(如果对于前缀索引外的条件需要其可以起到加速查询的目的,可以通过建立 Bloom Filter 过滤器加速。一般对于字符串类型建立即可,因为 Doris 针对列存在 Block 级别对于整型、日期已经有 Min/Max 索引)。

最后,看一个多张Rollup都可以命中的查询:

mysql> explain SELECT * FROM rollup_test1 WHERE k4 < 1000 AND k5 = 80 AND k6 >= 10000;
...
TABLE: default_cluster:example_db.rollup_test1(rollup_index3)
...

有 k4,k5,k6 三个条件,rollup_index3 以及 rollup_index4 的前3列分别含有这三列,所以两者匹配的前缀索引长度一致,选取两者都可以,当前默认的策略为选取了比较早创建的一张 rollup,这里为 rollup_index3。

修改以上查询,加入OR条件(不走任何索引),则这里的查询不能命中前缀索引。

mysql> explain SELECT * FROM rollup_test1  WHERE k4 < 1000 AND k5 = 80 OR k6 >= 10000;
...
TABLE: default_cluster:example_db.rollup_test1(rollup_test1)
...

​​​​​​​1.2 聚合数据

聚合数据仅用于聚合模型,即aggregate 和Unique(读时合并,Unique只是Aggregate模型的一个特例),在Duplicate模型中,由于Duplicate模型没有聚合的语境,所以该模型中的 ROLLUP,已经失去了“上卷”这一层含义,而仅仅是作为调整列顺序,以命中前缀索引的作用。

当然一般的聚合物化视图其聚合数据的功能是必不可少的,这类物化视图对于聚合类查询或报表类查询都有非常大的帮助,要命中聚合物化视图需要下面一些前提:

  1. 查询或者子查询中涉及的所有列都存在一张独立的 Rollup 中。
  2. 如果查询或者子查询中有 Join,则 Join 的类型需要是 Inner join。

以下是可以命中Rollup的一些聚合查询的种类:

 

注意:APPROX_COUNT_DISTINCT 类似Count Distinct ,速度快,返回近似值。

如果符合上述条件,则针对聚合模型在判断命中 Rollup 的时候会有两个阶段:

  1. 首先通过条件匹配出命中前缀索引索引最长的 Rollup 表。
  2. 然后比较 Rollup 的行数,选择最小的一张 Rollup,这里不是真正去查询对应rollup表中行数少的,而是找到rollup上卷聚合程度最高的,意味着行数最少

例如创建Base表rollup_test2以及Rollup:

#创建表 rollup_test2
CREATE TABLE IF NOT EXISTS example_db.rollup_test2
(
`k1` TINYINT,
`k2` SMALLINT,
`k3` INT,
`k4` BIGINT,
`k5` DECIMAL(9,3),
`k6` CHAR(5),
`k7` DATE,
`k8` DATETIME,
`k9` VARCHAR(20),
`k10` DOUBLE MAX,
`k11` FLOAT SUM
)
AGGREGATE KEY(`k1`,`k2`,`k3`,`k4`,`k5`,`k6`,`k7`,`k8`,`k9`)
DISTRIBUTED BY HASH(`k1`) BUCKETS 1
PROPERTIES (
"replication_allocation" = "tag.location.default: 1"
);

#给表rollup_test2 添加Rollup物化索引表,名称为rollup1
mysql> ALTER TABLE example_db.rollup_test2 ADD ROLLUP rollup1(k1,k2,k3,k4,k5,k10,k11);
Query OK, 0 rows affected (0.01 sec)

#给表rollup_test2 添加Rollup物化索引表,名称为rollup2
mysql> ALTER TABLE example_db.rollup_test2 ADD ROLLUP rollup2(k1,k2,k3,k10,k11);
Query OK, 0 rows affected (0.02 sec)

#向表rollup_test2 中插入如下数据
insert into example_db.rollup_test2 values 
(1,2,3,4,1.0,'a',"2023-03-01","2023-03-01 08:00:00","aaa",1.0,1.0),
(5,6,7,8,2.0,'b',"2023-03-02","2023-03-02 08:00:00","bbb",2.0,2.0);

#创建完成后,查看表中的物化索引信息
mysql> desc example_db.rollup_test2 all;

物化索引信息结果如下:

 查看如下查询命中rollup情况:

mysql> explain SELECT SUM(k11) FROM rollup_test2 WHERE k1 = 10 AND k2 > 200 AND k3 in (1,2,3);
...
TABLE: default_cluster:example_db.rollup_test2(rollup2)
...

以上命中rollup判断流程如下:首先判断查询是否可以命中聚合的 Rollup表,经过查上面的图是可以的,然后条件中含有 k1,k2,k3 三个条件,这三个条件 rollup_test2、rollup1、rollup2 的前三列都含有,所以前缀索引长度一致,然后比较行数显然 rollup2 的聚合程度最高行数最少所以选取 rollup2。

​​​​​​​2. Rollup物化索引注意点

  1. ROLLUP最根本的作用是提高某些查询的查询效率(无论是通过聚合来减少数据量,还是修改列顺序以匹配前缀索引)。因此ROLLUP的含义已经超出了“上卷”的范围。这也是为什么我们在源代码中,将其命名为 Materialized Index(物化索引)的原因。
  2. ROLLUP是附属于Base表的,可以看做是Base表的一种辅助数据结构。用户可以在Base表的基础上,创建或删除ROLLUP,但是不能在查询中显式的指定查询某 ROLLUP。是否命中ROLLUP完全由Doris系统自动决定。
  3. ROLLUP的数据是独立物理存储的。因此,创建的ROLLUP越多,占用的磁盘空间也就越大。同时对导入速度也会有影响(导入的ETL阶段会自动产生所有 ROLLUP 的数据),但是不会降低查询效率(只会更好)。
  4. ROLLUP的数据更新与Base表是完全同步的。用户无需关心这个问题。
  5. ROLLUP中列的聚合方式,与Base表完全相同。在创建ROLLUP无需指定,也不能修改。
  6. 查询能否命中ROLLUP的一个必要条件(非充分条件)是,查询所涉及的所有列(包括 select list 和 where 中的查询条件列等)都存在于该ROLLUP的列中。否则,查询只能命中Base表。
  7. 某些类型的查询(如count(*))在任何条件下,都无法命中ROLLUP。
  8. 可以通过 EXPLAIN your_sql; 命令获得查询执行计划,在执行计划中,查看是否命中 ROLLUP。

可以通过DESC tbl_name ALL; 语句显示Base表和所有已创建完成的ROLLUP。

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

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

相关文章

Stable Diffusion - 图像控制插件 ControlNet (OpenPose) 配置与使用

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/131591887 论文&#xff1a;Adding Conditional Control to Text-to-Image Diffusion Models ControlNet 是神经网络结构&#xff0c;用于控制预…

mybatis联查 字段重复问题 查询出来一致

联查的数据是不同&#xff0c;但是返回出来的数据是相同的 排查原因&#xff1a; 两个不同的实体类都有同一个字段code 解决办法&#xff1a; 在数据库字段column字段起个别名就可以

Spring 用注解更简单存取对象

Spring 用注解更简单存取对象 ​ 上一篇文章是最原始的创建使用&#xff0c;这篇主要是讲 Spring 更简单的存储和读取对象的核心是使用注解 ,也是日常生活企业用的最多的方法 “注解” 所以这篇的内容是很重要的 &#xff01;&#xff01;&#xff01; 文章目录 Spring 用注解…

基础篇--单片机简介

单片机简介 视频教程 单片机是什么 单片机&#xff1a;Single-Chip Microcomputer 单片微型计算机&#xff0c;是一种集成电路芯片 单片机有什么用&#xff1f; 单片机发展历程 单片机发展超势 CISC Vs RISC CISC和RISC举例 https://wenku.baidu.com/view/b074b0ed998fcc22b…

浅谈Acrel-2000电力监控系统在配电工程中的应用 安科瑞 许敏

摘 要&#xff1a;随着社会经济的快速发展&#xff0c;我国变电站正朝着现代化的方向不断发展&#xff0c;自动化设备以及继电保护装置凭借自身优异性能而获得广泛应用。本文介绍的AM5SE系列的微机保护装置&#xff0c;可以针对中原科技城智慧能源配电工程中不同保护对象提供对…

全志f1c200s嵌入式驱动开发(原理图)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 熟悉全志soc的同学都知道,除了v3s之外,其实还有很多性价比很高的soc。这里面就包含了f1c200s。之前的v3s,也就是我们所说的licheepi上面的soc,反响很不错。后期又出了一个liche…

【数据结构与算法】力扣:二叉树的层序遍历

给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 示例1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;[[3],[9,20],[15,7]] 示例 2&#xff1a; 输入&a…

纷享销客携手新奥动力,赋能能源装备制造业企业增长再提速

近日&#xff0c;纷享销客与新奥能源动力科技&#xff08;上海&#xff09;有限公司&#xff08;以下简称&#xff1a;新奥动力&#xff09;售后数字化平台项目启动仪式在上海顺利召开&#xff0c;新奥动力和纷享销客双方多位高管共同出席了当天的启动会&#xff0c;双方就CRM建…

leetcode链表刷题记录

题单&#xff1a; 一&#xff0c;移除链表元素 题目描述 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 题目接口&#xff1a; /*** Definition for singly-linked list.* struct Lis…

轻量化与强度:挑选骑行爱车的科学平衡之道

在自行车运动的大家庭中&#xff0c;挑选一辆既轻量化又强度又够的自行车是一项关键的任务。那么&#xff0c;如何在轻量化与强度的矛盾中寻找这个科学的平衡点呢&#xff1f;让我们跟随本文&#xff0c;一起探讨如何挑选骑行爱车的科学之道。 首先&#xff0c;我们需要明确&am…

第4章 SSD核心技术:FTL 4.3-4.5

4.3 垃圾回收 4.3.1 垃圾回收原理 WA&#xff08;Write Amplification&#xff09;&#xff0c;即写放大。 OP&#xff08;Over Provisioning&#xff09;&#xff0c;即预留空间。 4.3.2 写放大 对于空盘来说&#xff08;未触发GC&#xff09;&#xff0c;写放大一般为1&…

基于DarkFace数据集的高精度人脸检测系统(PyTorch+Pyside6+YOLOv5模型)

摘要&#xff1a;基于DarkFace数据集的高精度人脸检测系统可用于日常生活中来检测与定位人脸目标&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的人脸目标检测识别&#xff0c;另外支持结果可视化与图片或视频检测结果的导出。本系统采用YOLOv5目标检测模型训练…

volatile 原理

volatile 的底层实现原理是内存屏障&#xff0c;Memory Barrier&#xff08;Memory Fence&#xff09; 对 volatile 变量的写指令后会加入写屏障对 volatile 变量的读指令前会加入读屏障 如何保证可见性 写屏障&#xff08;sfence&#xff09;保证在该屏障之前的&#xff0c…

液晶仪表业务去年赚了4个亿,又一家汽车电子厂商冲刺IPO

液晶仪表&#xff0c;有多赚钱&#xff1f; 本周&#xff0c;随着天有为电子首次对外发布IPO招股说明书&#xff0c;这家专注于电子式组合仪表、全液晶组合仪表和双联屏仪表等产品的传统汽车仪表企业&#xff0c;揭开了过去几年的财务数据。 作为一家传统汽车仪表转型升级的典…

sqlserver导入外部数据文件

1、外部数据文件存为txt格式&#xff0c;可以带中文标题保存。 2、登录链接数据库服务器&#xff0c;选择任意一个数据库右键-任务-导入数据-数据源&#xff1a;选择Flat File Sourse 平面文件.-文件名&#xff1a;选择文件路径-浏览一下列是否对应上。-下一步-目标&#xff1a…

WebStorm配置代码模板【以vue模板为例,提供vue代码模板】

配置过程 引言 为了便于开发&#xff0c;提高生产效率&#xff0c;我们通常会复制粘贴一些共同代码&#xff0c;在WebStorm中&#xff0c;可以将这些共同代码制作成模板&#xff0c;在使用的时候&#xff0c;只需要输入关键字点击按键即可将模板的代码粘贴到代码文件中&#…

免费申域名

申请地址&#xff1a;https://nic.eu.org/ 英国人地址生成器&#xff1a;https://www.shenfendaquan.com/Index/index/ying_guo_shen_fen_sheng_cheng 1、注册 填写注册信息 进入注册页面&#xff0c;输入注册信息。这里我们打开英国人地址生成器&#xff0c;用英国的信息注…

数据库应用:MySQL数据库使用与管理

目录 一、理论 1.MySQL基本操作 2.数据类型 2.使用MySQL数据库 二、实验 1.查看数据库结构 2.创建及删除库和表 3.管理表中的数据记录 4.修改表名和表结构 5.查看、修改字符集 三、问题 1.表导入新记录报错 四、总结 一、理论 1.MySQL基本操作 &#xff08;1&…

【sql注入-延时注入】sleep()、benchmark()函数 延时注入

目录 sleep()、benchmark()延时注入 一、语法介绍&#xff1a; 二、延时注入 三、不同数据库 网络安全小圈子 sleep()、benchmark()延时注入 一、语法介绍&#xff1a; 版本&#xff1a; sleep() MySQL>5.7.8 benchmark() MySQL>5.7.5 语法&#xff1a; 使用…

孤立随机森林(Isolation Forest)(Python实现)

目录 1 简介 2 孤立随机森林算法 2.1 算法概述 2.2 原理介绍 2.3 算法步骤 3 参数讲解 4 Python代码实现 5 结果 1 简介 孤立森林&#xff08;isolation Forest&#xff09;是一种高效的异常检测算法&#xff0c;它和随机森林类似&#xff0c;但每次选择划分属性和划分点&…