项目背景

指标管理平台按指标查询类型可以划为落表指标和即席查询指标。

  • 落表指标:可选择不同的维度生成多个结果表(每天提交任务写入结果表),对指标进行取数的时候会根据查询条件自动匹配最合适的结果表进行查询。

  • 即席查询指标:不产生结果表,每次取数根据指标计算规则以及查询条件动态生成SQL去指标来源表中查询

举例说明:现有一张订单明细表 order_info,表结构如下

CREATE TABLE order_info (

order_id varchar(64) NOT NULL COMMENT "订单id",

pt varchar(12) NOT NULL COMMENT "用户id",

user_id varchar(64) NOT NULL COMMENT "用户id",

price double NULL COMMENT "",

project_id int(11) NOT NULL COMMENT "产品id",

channel varchar(64) NULL COMMENT "渠道"

) ENGINE=OLAP

PRIMARY KEY(order_id,pt)

PARTITION BY (pt)

DISTRIBUTED BY HASH(order_id)

PROPERTIES ( "replication_num" = "3",

"in_memory" = "false",

"enable_persistent_index" = "true",

"replicated_storage" = "true",

"compression" = "LZ4"

);

构建指标

(1)创建模型:示例只有单表不需要增加关联,选择price作为度量列,user_id、project_id、channel作为维度列。

(2)创建原子指标:销售额、计算逻辑 sum(price) , 维度为模型的全部维度。

(3)构建落表派生指标:当日销售金额、指标计算逻辑 sum(price) , 落表维度分别选择 channel (渠道当日销售金额), project_id (产品当日销售金额)

-- 渠道当日销售金额

create table sum_price_day_channel as

select sum(price) as sum_price_day , channel , '{pt}'

from order_info where pt = '{pt}' group by channel;

-- 产品当日销售金额

create table sum_price_day_project as

select sum(price) as sum_price_day , project_id , '{pt}'

from order_info where pt = '{pt}' group by project_id;

(4)构建即席查询派生指标:当日销售金额、指标计算逻辑 sum(price), 支持维度选择 channel、project_id。

查询指标

(1)根据维度channel ,20250101<= pt <= 20250105 查询

a.即席查询:实时生成sql

select sum(price) as sum_price_day,channel,pt

from order_info

where pt >= '20250101' and pt <= '20250105'

group by channel,pt

b.落表查询:当 sum_price_channel 表包含所有需要查询的日期,否则根据即席查询生成sql获取数据。

-- 当sum_price_channel包含所有查询日期

select sum_price_day,channel,pt

from sum_price_day_channel

where pt >= '20250101' and pt <= '20250105'

(2)根据维度channel、project ,20250101<= pt <= 20250105 查询

因为落表指标没有同时包含channel、project_id的结果表则走即席查询逻辑

select sum(price) as sum_price_day,channel,project_id,pt

from order_info

where pt >= '20250101' and pt <= '20250105'

group by channel,project_id,pt

StarRocks物化视图

同步物化视图

限制

只支持单表

本质上是基表的索引而不是物理表

语法

CREATE MATERIALIZED VIEW [IF NOT EXISTS] [database.]<mv_name>

[COMMENT ""]

[PROPERTIES ("key"="value", ...)]

AS

<query_statement>

异步物化视图

基于default_catalog为基表创建的异步物化视图,StarRocks 通过排除数据与基表不一致的物化视图,来保证改写之后的查询与原始查询结果的强一致性。External Catalog 创建的物化视图由于异步刷新机制,查询结果可能与基表上查询的结果不一致。

限制

  • 异步物化视图不支持使用 List 分区策略,不支持基于使用 List 分区的基表创建。

  • 查询改写只支持Cardinality Preservation Join(结果集行数不会超过输入表中的任意一方)

  • 不支持grouping set、grouping set with rollup 以及 grouping set with cube 的查询改写

  • 分区物化视图只支持 Range 分区

语法

CREATE MATERIALIZED VIEW [IF NOT EXISTS] [database.]<mv_name>

[COMMENT ""]

-- 必须至少指定

distribution_desc

refresh_scheme 其中之一。

-- distribution_desc[DISTRIBUTED BY HASH(<bucket_key>[,<bucket_key2> ...]) [BUCKETS <bucket_number>]]

-- refresh_desc[REFRESH

-- refresh_moment

[IMMEDIATE | DEFERRED]

-- refresh_scheme

[ASYNC | ASYNC [START (<start_time>)] EVERY (INTERVAL <refresh_interval>) | MANUAL]]

-- partition_expression

[PARTITION BY {<date_column> | date_trunc(fmt, <date_column>)}]

-- order_by_expression

[ORDER BY (<sort_key>)][PROPERTIES ("key"="value", ...)]AS <query_statement>

手动刷新视图

-- 异步调用刷新任务。

REFRESH MATERIALIZED VIEW <mv_name>;

-- 同步调用刷新任务。

REFRESH MATERIALIZED VIEW <mv_name> WITH SYNC MODE;

查询加速

方案一:于StarRocks物化视图加速即席指标

StarRocks 查询改会校验是否可以复用已有物化视图中的预计算结果处理查询,如果不能复用会去原表查询,保证数据一致性。

(1)基于原子指标创建异步物化视图

CREATE MATERIALIZED VIEW sum_price_view

REFRESH ASYNC START('2025-05-01 09:00:00') EVERY (interval 1 day)

AS

SELECT

sum(price),user_id,project_id,channel,pt

FROM order_info group by user_id,project_id,channel,pt;

(2)根据维度channel ,20250101<= pt <= 20250105 查询

即席查询生成sql

select sum(price) as sum_price_day,channel,pt

from order_info

where pt >= '20250101' and pt<= '20250105'

group by channel,pt

因为有sum_price物化视图,StarRocks会改写查询

select sum(price) as sum_price_day,channel,pt

from sum_price_view

where pt >= '20250101' and pt <= '20250105'

group by channel,pt

从而达到查询加速的目的。

方案二:基于StarRocks物化视图加速

落表指标落表指标只生成最多维度结果表,其他结果表基于最全结果表使用同步物化视图代替。

(1)与方案一一样也基于原子指标创建物化视图

(2)创建所有已选维度的结果表,结果表使用range分区

-- 结果表分区字段设置为date类型,分区方式使用时间表达式分区

-- 主键修改为bigint类型自增

CREATE TABLE IF NOT EXISTS sum_price_day_channel_project_id (

pk bigint AUTO_INCREMENT,

pt datetime,

sum_price_day DOUBLE,

channel string,

project_id int(11)

)

PRIMARY KEY (pk,pt)

PARTITION BY date_trunc('day',pt)

DISTRIBUTED BY HASH(pk)PROPERTIES (

"enable_persistent_index" = "true");

-- 基于所有维度结果表创建异步分区物化视图

CREATE MATERIALIZED VIEW sum_price_day_channel_view

REFRESH ASYNC

PARTITION BY pt

AS

SELECT

sum(sum_price_day),channel

FROM sum_price_day_channel_project_id

where pt = '{pt}'group by channel;

CREATE MATERIALIZED VIEW sum_price_day_project_view

REFRESH

ASYNC

PARTITION BY pt

AS

SELECT

sum(sum_price_day),project_id

FROM sum_price_day_channel_project_id

where pt = '{pt}'

group by project_id;

(3)落表指标任务 sql 利用物化视图自动刷新机制,查询sum_price_day_channel_view、sum_price_day_project_view 数据会与sum_price_day_channel_project_id结果一致,并支持查询改写。

insert OVERWRITE sum_price_day_channel_project_id PARTITION(pt='20250501') (pt,sum_price_day,channel,project_id)

select str2date('20250501', '%Y%m%d'),idx.sum_price_day,idx.channel,idx.project_id from

( select sum(price) as sum_price_day ,channel, project_id from order_info where pt = '{pt}'

group by project_id,channel,project_id;)idx

基于以上操作可以减少导入结果表次数加速任务运行,简化取数sql结合StarRocks查询改写提升查询性能。

方案三:其他优化

通过字典转换string类型为integer类型提升效率。

有序的排序聚合 (Sorted streaming aggregate),利用排序键提高group性能。

Colocate Join 通过指定 "colocate_with" = "group_name" 参数,使相同维度数据保持在同一组 BE 节点上,从而减少数据在节点间的传输耗时,提升join性能。

(1)创建字典表并导入数据。

CREATE TABLE channel_dict (

channel STRING,

channel_int BIGINT AUTO_INCREMENT

)

PRIMARY KEY (channel)

DISTRIBUTED BY HASH(channel)

PROPERTIES("replicated_storage" = "true");

CREATE TABLE order_id_dict (

order_id STRING, order_id_int BIGINT AUTO_INCREMENT )

PRIMARY KEY (order_id)

DISTRIBUTED BY HASH(order_id)

PROPERTIES("replicated_storage" = "true");

CREATE TABLE user_id_dict (

user_id STRING,

user_id_int BIGINT AUTO_INCREMENT

)

PRIMARY KEY (user_id)

DISTRIBUTED BY HASH(user_id)

PROPERTIES("replicated_storage" = "true");

-- 导入数据

insert into channel_dict(channel) select distinct channel from order_info;

insert into order_id_dict(order_id) select distinct order_id from order_info;

insert into user_id_dict(user_id) select distinct user_id from order_info;

(2)创建包含channel_integer的结果表并导入数据。

CREATE TABLE order_info_integer (

order_id varchar(64) NOT NULL COMMENT "订单id",

pt varchar(12) NOT NULL COMMENT "用户id",

user_id varchar(64) NOT NULL COMMENT "用户id",

price double NULL COMMENT "",

project_id int(11) NOT NULL COMMENT "产品id",

channel varchar(64) NULL COMMENT "渠道"

-- 该列是配置 dict_mapping 的生成列,在导入数据时其列值自动从示例一中的字典表 dict 中获取。

-- 后续可以直接基于该列进行去重和 JOIN 查询。

channel_int BIGINT AS dict_mapping('channel_dict', channel),

order_id_int BIGINT AS dict_mapping('order_id_dict', order_id),

user_id BIGINT AS dict_mapping('user_id_dict', user_id)

)ENGINE=OLAP

PRIMARY KEY(order_id,pt)

PARTITION BY (pt)

DISTRIBUTED BY HASH(order_id)

PROPERTIES (

"replication_num" = "3",

"in_memory" = "false",

"enable_persistent_index" = "true",

"replicated_storage" = "true",

"compression" = "LZ4"

);

insert into order_info_integer(order_id,pt,user_id,price,project_id)

select order_id,pt,user_id,price,project_id from order_info;

(3)结果表存储以及后续关联都是用integer字段,会加速查询关联查询。

这个方案会产生字典数据,查询时需要查字典表进行id转换,会带来一定开销,适合关联比较频繁的场景使用

基于 StarRocks 的指标平台查询加速方案的更多相关文章

  1. 基于ArcGISServer进行分页矢量查询的方案进阶

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.    背景 在空间查询中,我们对查询结果要求以分页形式进行展示.G ...

  2. 基于Solr的多表join查询加速方法

    前言 DT时代对平台或商家来说最有价值的就是数据了,在大数据时代数据呈现出数据量大,数据的维度多的特点,用户会使用多维度随意组合条件快速召回数据.数据处理业务场景需要实时性,需要能够快速精准的获得到需 ...

  3. 李呈祥:bilibili在湖仓一体查询加速上的实践与探索

    导读: 本文主要介绍哔哩哔哩在数据湖与数据仓库一体架构下,探索查询加速以及索引增强的一些实践.主要内容包括: 什么是湖仓一体架构 哔哩哔哩目前的湖仓一体架构 湖仓一体架构下,数据的排序组织优化 湖仓一 ...

  4. 基于token的多平台身份认证架构设计

    基于token的多平台身份认证架构设计 1   概述 在存在账号体系的信息系统中,对身份的鉴定是非常重要的事情. 随着移动互联网时代到来,客户端的类型越来越多, 逐渐出现了 一个服务器,N个客户端的格 ...

  5. 基于GPU的图像处理平台

    基于GPU的图像处理平台 1.  (309)英伟达推Jetson TX1 GPU模块力推人工智能 1.1 产品概述 Jetson TX1 GPU模块,主要针对近年来蓬勃发展的人工智能市场,包括无人机. ...

  6. “DNAT+云链接+CDN”加速方案,助力出海企业落地生长

    摘要:“DNAT+云链接+CDN”加速方案,真正释放技术红利,真诚助力企业出海. 随着国内互联网行业的人口红利逐渐消失,本土互联网市场竞争不断加剧,加之国家多项“走出去”政策的推动,越来越多的中国互联 ...

  7. 释放至强平台 AI 加速潜能 汇医慧影打造全周期 AI 医学影像解决方案

    基于英特尔架构实现软硬协同加速,显著提升新冠肺炎.乳腺癌等疾病的检测和筛查效率,并帮助医疗科研平台预防"维度灾难"问题 <PAGE 1 LEFT COLUMN: CUSTOM ...

  8. Iceberg 数据治理及查询加速实践

    数据治理 Flink 实时写入 Iceberg 带来的问题 在实时数据源源不断经过 Flink 写入的 Iceberg 的过程中,Flink 通过定时的 Checkpoint 提交 snapshot ...

  9. Atitit  基于meta的orm,提升加速数据库相关应用的开发

    Atitit  基于meta的orm,提升加速数据库相关应用的开发 1.1. Overview概论1 1.2. Function & Feature功能特性1 1.2.1. meta api2 ...

  10. 白瑜庆:知乎基于Kubernetes的kafka平台的设计和实现

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文首发在云+社区,未经许可,不得转载. 自我介绍 我是知乎的技术中台工程师,现在是负责知乎的存储相关组件.我的分享主要基于三个,一个是简单 ...

随机推荐

  1. 14 个 Linux 下 CPU 监控工具

    01. top top是最常用的查看系统资源使用情况的工具,包括CPU.内存等等资源. 这里主要关注CPU资源. 1.1 /proc/loadavg load average取自/proc/loada ...

  2. 关于Linux的core dump

      core dump简介 core dump就是在进程crash时把包括内存在内的现场保留下来,以备故障分析. 但有时候,进程crash了却没有输出core,因为有一些因素会影响输出还是不输出cor ...

  3. 【python-数据分析】pandas时间序列处理

    1. timestamp 1.1 创建timestamp 自定义timestamp 语法:pd.Timestamp(ts_input,tz,year,month,day,hour,minute,sec ...

  4. 深入理解Hadoop读书笔记-2

    背景 公司的物流业务系统目前实现了使用storm集群进行过门事件的实时计算处理,但是还有一个需求,我们需要存储每个标签上传的每条明细数据,然后进行定期的标签报表统计,这个是目前的实时计算框架无法满足的 ...

  5. 卧槽!C 语言宏定义原来可以玩出这些花样?高手必看!

    大家好啊!我是小康. 今天我们来聊一个听起来枯燥但实际上暗藏玄机的话题 -- C 语言的宏定义. 啥?宏定义?那不就是个简单的替换工具吗? 兄dei,如果你也是这么想的,那可就大错特错了!宏定义在 C ...

  6. 【SpringMVC】使用 @RequestMapping 映射请求

    使用 @RequestMapping 映射请求 Spring MVC 使用 @RequestMapping 注解为控制器指定可以处理哪些 URL 请求 在控制器的类定义及方法定义处都可标注 @Requ ...

  7. 【数据结构与算法】第K大的元素:三路快速排序算法思路

    第K大的元素:三路快速排序算法思路 Java https://leetcode-cn.com/problems/kth-largest-element-in-an-array/solution/di- ...

  8. Python科学计算系列1—方程和方程组

    1.一元方程求解 例1:求下列一元二次方程的解 代码如下: # 定义数学符号 from sympy import symbols, solve x = symbols('x') f = x ** 2 ...

  9. Clion搭建C语言开发环境

    1.下载和安装MinGW 1)下载链接:http://www.mingw.org/ 2)选择安装目录,目录尽可能简单(如:D:\MinGW)且不要包含中文和空格 3)添加相关的包 所需的包如下:min ...

  10. 深入理解Java虚拟机-JAVA内存模型与线程

    Java内存模型(JMM) JMM 的核心概念 主内存与工作内存: 主内存(Main Memory)是所有线程共享的内存区域,存放着所有变量的值 每个线程都有自己的 工作内存(Working Memo ...