海山数据库(He3DB)原理剖析:浅析OLAP数据库计算引擎中的统计信息

news2025/6/20 5:26:44

背景:

统计信息在计算引擎的优化器模块中经常被提及,尤其是在基于成本成本优化(CBO)框架中统计信息发挥着至关重要的作用。CBO旨在通过评估执行查询的可能方法,并选择最有效的执行计划来提高查询性能。而统计信息则提供了关于数据分布、数据倾斜等方面的关键信息,帮助CBO做出最优的决策。无论是传统数据库MySQL、PostgreSQL,还是Hive、Spark计算引擎、Doris、StarRocks 等OLAP引擎,都针对CBO模块做了大量开发工作。而统计信息作为影响CBO决策的最重要因素,计算引擎需要对统计信息的搜集、加工、利用多个阶段进行打磨优化,最终帮助用户业务提供成本最低的执行计划。

本文将会从统计信息的常见来源以及计算引擎如何利用统计信息多个方面着手,综合多个计算引擎的CBO统计信息框架优化案例,浅析计算引擎的CBO统计信息。

图1 计算引擎的优化器模块

一、统计信息的种类与来源

综合多个计算引擎的统计信息集成情况,可以发现大家获取统计信息手段不尽相同,一种是精准搜集统计信息,一种是采用多种手段对数据进行评估获取统计信息。

常见的基本统计信息类型有min/max/ndv/totalSize/fileNum,各家计算引擎会根据引擎特点继续扩展不同的统计信息,如涉及到数据整体评估的统计信息,MVC(高频非NULL值)、HiSTOGRAM(直方图)等。

1、基本类型统计信息

基本统计类型是相对精准的信息,一般用户analyze语句获取的统计信息多数是这种min/max等基本信息。一般表级别、分区级别、字段级别都会有相应的统计信息。在不同的SQL业务中,计算引擎会根据SQL中的谓词语句、table scan的具体表来分别利用哪种统计信息。

如select count(*) from testtbl; 显然这条语句会用到表级别统计信息,select count(distinct id) from testtbl where date=2024; 这条语句一般就会用到分区date以及字段id的统计信息。

基本类型统计信息一般都是实时获取+定时任务获取。如大数据中Hive每次执行写入任务之后会有线程启动搜集写入数据的基本统计信息,一定程度上保证统计信息实时准确,StarRocks会有定时任务自动执行内表的统计信息搜集。

2、估算类型统计信息

估算类型统计信息一般泛指对数据集的一个整体评估,能够在牺牲一定的准确性的情况下给出数据集的一个分布情况,常见的如MVC。这种统计信息适合对于在大规模数据集下,基本统计信息搜集相对代价较高且基本统计信息缺乏对整体数据集的极端分布(如数据倾斜)的体现,而估算类型的统计信息能够告诉计算引擎数据的分布状况,能够使任务避免数据倾斜等情况。

一般评估数据分布的统计信息都会采用histogram直方图,多数计算引擎根据自身的业务特性实现了不同的直方图。直方图的基本原理是将数据排序后分成若干个bucket桶,并记录每个桶中数据的最大值、最小值、频次出现等信息。常见的直方图有Equal-width Histogram、Equi-height Histogram等。像Doris和StarRocks,均实现了Equi-height Histogram。Equi-width Histogram(等宽直方图)是将数据最大、小值之间的区间等分为N份,每个桶中最大、小值之差都为整体数据最大、小值之差/N,既所谓“等宽”。

Equi-height Histogram(等高直方图),它的桶宽度并不相等,取而代之的是,等高直方图会保证每个桶中数值的频次之和接近总行数的 1/N,就是落入每个桶里的值数量尽量相等。数据数据分布范围比较大时也可以很好的保证误差。各种计算引擎会根据其擅长的业务特性去改进直方图,以尽可能避免直方图落入局部最优的境地,这里不过多详细解释直方图实现原理,大家可以参考直方图的基本原理以及具体计算引擎实现去做细致研究。

一般情况下,估算类型统计信息能够相对准确、相对高效的应用在一些大数据量的表上,尤其是一些数据湖的大表(PB级别),但是一般的估算统计信息实现还是需要对数据做一遍整体扫描,所以多数情况下的实现会判断大小表来决定是否整体数据评估信息搜集还是采样搜集。判断是否整体还是采样搜集各家计算引擎都会有不同的规则,如StarRocks、Doris([Enchancement](statistics) Support sampling collection of statistics by weizhengte · Pull Request #18880 · apache/doris · GitHub)搜集histogram直方图统计信息支持设置最大行数采样、根据比例进行采样;也有的利用统计学方式如伯努利采样PrestoDB(Add reservoir_sample aggregation function by ZacBlanco · Pull Request #21296 · prestodb/presto · GitHub)。

apache datasketches是另一种可用的非常高效的数据分布计算工具, 目前基于apache datasketches算法库实现的直方图统计信息如Hive4.0,草图中实现了各种近似估算方法,很多方法都来源于数据库领域的论文算法。Sketch 结构即「数据草图」结构,主要是为了计算海量的流式数据的概率指标而设计的一种数据结构。

一般占用固定大小的内存,不随着数据量的增加而增大。这种结构通过巧妙地保存或丢弃一些数据的策略,将数据流的信息抽象存储起来,汇总成 Sketch 结构,最终能根据 Sketch 结构还原始数据的分布,实现基数统计、分位数计算等操作。

Spark3.5之后也使用apache datasketches实现了一些估算函数如ndvApache Spark ❤️ Apache DataSketches: New Sketch-Based Approximate Distinct Counting | Databricks Blog ,基于sketch的估算函数能有效加速Spark对大数据集的一些数据分布估算,比如在此之前,统计数据集中的ndv,一般spark用户都会count(distinct),这种计算十分耗时,而且计算结果不会有临时存储,每次都需要重新计算,而datasketch能够利用经过验证的统计学算法,快速的返回计算结果,结果还可以持久化到sketch的存储中,能够大大加速一些统计类型查询。

二、统计信息带来的常见收益

我们常常说统计信息能够加速查询,能够优化执行计划,那么从计算引擎角度来说,统计信息利用最多的地方有哪些呢?这里列举几个关键的点,我们可以从不同的计算引擎中了解统计信息是怎样给用户的业务带来加速。

1、join选择

join能力是考量OLAP引擎的关键指标。如何在复杂的SQL语句中找到优化的join方式是CBO优化要做的事情。分析中常见的hash join,涉及到大小表join,一个关键的因素是怎么判断表的大小,最直接的指标就是表的统计信息,优化器根据表大小,把小表作为build side来构造哈希表放入内存,大表作为probe side,这样可以有效避免数据的shuffle过程,主流的计算引擎都会支持这种高效的join方式。

还有join reorder优化,经常会根据计算过程中生成的临时统计信息对执行计划动态调整,修改join算法,简而言之,join优化的基本要素就是需要有相对准确的统计信息,最直接的统计信息如rowCount判断表大小。计算引擎一般利用这些基础的统计信息再结合一些reorder算法或者自定义的规则,完成join查询的最优执行路径选择。

2、自适应任务执行

Adaptive Query Execution即AQE也是计算引擎高阶优化经常谈到的一个点。AQE执行可以理解为动态CBO,可以根据运行期的一些临时数据的统计信息,动态调整CBO选择的执行路径。典型的一个是Spark AQE,其根据在运行时统计信息(runtime statistics)在查询执行的过程中进行动态(Dynamic)Spark的查询优化,AQE可以Spark运行query stage阶段准确获取统计信息,然后进行CBO优化剩余的stage,可以有效的动态合并Spark shuffle分区,避免join阶段的一些数据倾斜问题。

无独有偶,除了Spark AQE,其他计算引擎也都有很多类似AQE优化。(个人理解AQE优化一般针对中间数据有落盘的计算过程,如上面提到的Spark(shuffle阶段),所以可以推测其他有中间数据可以物化/落盘行为的计算引擎也可以去做这种优化。)。

TrinoDB近年来增强了自身的容错计算能力,即设计了中间shuffle数据落盘的一种计算模式(fte),可以在部分task运行失败时从磁盘中恢复中间执行数据然后重新执行,TrinoDB的这种fte模式很适合使用AQE优化,用于减少运行期启动不必要的task,如Adaptive planning framework in FTE by gaurav8297 · Pull Request #20276 · trinodb/trino · GitHub 就是利用运行期统计信息做一些自适应优化;

PrestoDB虽然没有fte执行模式,但是其曾经也做过一些中间数据物化以提高task容错的开发如[Design] Exchange Materialization · Issue #12387 · prestodb/presto · GitHub ,其思想会把中间数据物化成一个临时表供下游task消费,那么很显然的优化就是获取这个中间表的统计信息来对下游的CBO执行计划做动态自适应调整Initial Support of Adaptive Optimization with Presto Unlimited by pguofb · Pull Request #14675 · prestodb/presto · GitHub。

类似的,Hive3其实就有AQE优化,核心思想缓存中间运行期的统计信息,动态修正CBO执行计划、动态调整分区裁剪优化等[HIVE-17626] Query reoptimization using cached runtime statistics - ASF JIRA 。所以,一旦清楚了AQE思想,每一种计算引擎都可以根据自己运行期的统计信息特点做进一步动态优化,给与业务最好的加速体验。

3、聚合下推优化

计算引擎中的聚合算子如sum、count是相对比较消耗计算资源的操作,常规执行逻辑就是扫描数据的每一行来进行各种加减操作。但是如果已经搜集了存储表的统计信息如rowCount,那么像这种count算子就是一个O(1)的简单元数据操作,计算引擎不需要计算直接返回已经搜集的统计信息即可。

这种聚合下推的优化在各个计算引擎中基本都有实现,尤其是针对底层存储采用Parquet/ORC这种开发式列存的文件格式(如Iceberg的metadata文件就记录了详细的Parquet/ORC统计信息),如Spark利用Iceberg的统计信息,做一些下推的优化操作,如TrinoDB也做了类似的基于统计信息的聚合下推操作优化Add aggregation pushdown support for count using Iceberg Metrics by osscm · Pull Request #15832 · trinodb/trino · GitHub 。

当然,Hadoop之上经典的Hive计算引擎也早就有这种聚合下推优化,比如有些Hive优化参数会控制是否启动MR分布式任务,如参数hive.compute.query.using.stats,该参数开启的情况下,Hive计算引擎会去判断当前表的统计信息rowCount是否最新,如果统计信息最新,则在SQL语句中涉及到count的操作算子直接通过统计信息返回,避免了启动分布式任务去计算。

三、小结

无论是数据库领域还是大数据领域,CBO优化都是非常重要,而统计信息则是作为CBO优化的最关键一环,每一种计算引擎都会根据自身擅长的业务特点进行统计信息的搜集/利用,从而获得最佳的执行计划。如何准确且轻量地获取统计信息,并合理地应用在CBO框架以及其他优化中,是一个非常值得探索的方向。

四、作者介绍

张步涛,中国移动云能力中心数据库产品部-OLAP数据库开发工程师。主要参与OLAP内核研发/湖仓一体研发相关工作。

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

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

相关文章

Qt for MCUs 2.7正式发布

本文翻译自:Qt for MCUs 2.7 released 原文作者:Qt Group高级产品经理Yoann Lopes 翻译:Macsen Wang Qt for MCUs的新版本已发布,为Qt Quick Ultralite引擎带来了新功能,增加了更多MCU平台的支持,并且我们…

全光谱台灯哪个牌子好,2024全光谱护眼台灯推荐

近年来,全光谱台灯悄然跻身于家庭必备品之列,赢得了众多消费者的好评。它们以减轻眼睛疲劳的功效而受到推崇,尽管也有声音质疑其实际效用,认为所谓的益处不过是一种心理安慰。面对这些相互矛盾的观点,许多消费者感到困…

武汉星起航:深挖跨境电商潜力,助力创业者全球拓展

随着全球化进程的加速,跨境电商已成为推动国际贸易发展的新生力量。这一新模式的兴起,得益于互联网、物流和支付技术的深度融合,它不仅打破了地域限制,促进了商品和服务的全球流通,还为消费者带来了更多选择&#xff0…

即插即用篇 | YOLOv5/v7引入Haar小波下采样 | 一种简单而有效的语义分割下采样模块

本改进已集成到 YOLOv5-Magic 框架。 下采样操作如最大池化或步幅卷积在卷积神经网络(CNNs)中被广泛应用,用于聚合局部特征、扩大感受野并减少计算负担。然而,对于语义分割任务,对局部邻域的特征进行池化可能导致重要的空间信息丢失,这有助于逐像素预测。为了解决这个问题…

STC89C52学习笔记(八)

STC89C52学习笔记(八) 综述:本文讲述了LED点阵屏、如何进行数据串行输入,并行输出以及LED点阵屏显示一列多列图形。 一、LED点阵屏 1.介绍 LED点阵屏由多个LED组成,以矩阵形式排列(类似于矩阵键盘&…

分布式锁-redission

5、分布式锁-redission 5.1 分布式锁-redission功能介绍 基于setnx实现的分布式锁存在下面的问题: 重入问题:重入问题是指 获得锁的线程可以再次进入到相同的锁的代码块中,可重入锁的意义在于防止死锁,比如HashTable这样的代码…

作业习题

实验代码: import java.util.Scanner;class chazhao {public static void main(String[] args) {Scanner scnew Scanner(System.in);System.out.println("请输入你要的数组");String line sc.nextLine();String[] lineArrline.split(" ");int[…

Mybatis分页查询用PageHelper插件

首先看接口文档需求 看响应数据样例,那么咱们先自定义一个bean来满足这个需求,这里定义PageBean实体类 package com.itheima.pojo;import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;import java.util.List;//分…

uniapp+springboot实现一个简单的音乐播放器移动端+服务端(第一阶段计划有流程制定)

一、项目概述 本项目旨在通过uniapp开发移动端音乐播放器,并利用Spring Boot构建后端服务,实现用户登录、音乐列表获取、音乐播放与暂停、音乐收藏等功能。 二、开发流程 需求分析 确定音乐播放器的核心功能,如用户登录、音乐列表展示、音乐播…

STM32 H7系列学习笔记

必备的API知识 第 1 步:系统上电复位,进入启动文件 startup_stm32h743xx.s,在这个文件里面执行复位中断服务程序。 在复位中断服务程序里面执行函数 SystemInit,在system_stm32h7xx.c 里面。*之后是调用编译器封装好的函数&…

R语言复现:轨迹增长模型发表二区文章 | 潜变量模型系列(2)

培训通知 Nhanes数据库数据挖掘,快速发表发文的利器,你来试试吧!欢迎报名郑老师团队统计课程,4.20直播。 案例分享 2022年9月,中国四川大学学者在《Journal of Psychosomatic Research》(二区,I…

第十届蓝桥杯大赛个人赛省赛(软件类) CC++ 研究生组2.0

A立方和 #include<iostream> #include<cmath> using namespace std; int main(){int n, t, flag, x;long long ans 0;for(int i 1; i < 2019; i){t i;flag 0;while(t && !flag){x t % 10;if(x 2 || x 0 || x 1 || x 9) flag 1;t / 10;}if(fl…

1571. 【基础赛】游戏(game)

1571. 【基础赛】游戏&#xff08;game&#xff09; (Input: game.in, Output: game.out) 题目描述 Introl 在玩一种特殊的游戏——凑顺子。 他现在有 n 张牌&#xff0c;每张牌的点数为 ai​&#xff0c;他希望凑出尽可能多的顺子。 在该游戏中&#xff0c;顺子的定义为&…

【c++】string类常见接口函数

&#x1f525;个人主页&#xff1a;Quitecoder &#x1f525;专栏&#xff1a;c笔记仓 朋友们大家好啊&#xff0c;本节我们来到STL内容的第一部分&#xff1a;string类接口函数的介绍 目录 1.string类的认识2.常见接口讲解2.1 string类对象的常见构造2.2 对string对象的遍历和…

day7 nest商业项目初探·三(java转ts全栈/3R教室)

背景&#xff1a;从头一点点学起太慢了&#xff0c;直接看几个商业项目吧&#xff0c;看看根据Java的经验&#xff0c;自己能看懂多少&#xff0c;然后再系统学的话也会更有针对性。今天看下一个项目 * 【法国 | 3.75w】Nextjs&#xff1a;小雯工作室创意官网 &#xff08;2023…

【Java】Java使用Swing实现一个模拟计算器(有源码)

&#x1f4dd;个人主页&#xff1a;哈__ 期待您的关注 今天翻了翻之前写的代码&#xff0c;发现自己之前还写了一个计算器&#xff0c;今天把我之前写的代码分享出来。 我记得那会儿刚学不会写&#xff0c;写的乱七八糟&#xff0c;但拿来当期末作业还是不错的哈哈。 直接上…

48-基于腾讯云EKS的容器化部署实战

准备工作 在部署IAM应用之前&#xff0c;我们需要做以下准备工作&#xff1a; 开通腾讯云容器服务镜像仓库。安装并配置Docker。准备一个Kubernetes集群。 开通腾讯云容器服务镜像仓库 在Kubernetes集群中部署IAM应用&#xff0c;需要从镜像仓库下载指定的IAM镜像&#xff…

基于springboot实现医院管理系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现医院管理系统演示 摘要 随着信息互联网信息的飞速发展&#xff0c;医院也在创建着属于自己的管理系统。本文介绍了医院管理系统的开发全过程。通过分析企业对于医院管理系统的需求&#xff0c;创建了一个计算机管理医院管理系统的方案。文章介绍了医院管理系…

【YOLOv8实战】手把手带你入门YOLOv8,你也能训练自己的检测器,以SAR目标检测为例(源码+数据集+Gradio界面)

&#x1f4a1;&#x1f4a1;&#x1f4a1;本文摘要&#xff1a;基于YOLOv8的SAR图像目标检测系统&#xff0c;覆盖数据制作、数据可视化、模型训练/评估/推理/部署全流程&#xff0c;最后通过 Gradio 界面进行展示。 0 写在前面 上篇分享【飞浆AI实战】交通灯检测&#xff1a…

抖音视频无水印采集拓客软件|视频批量下载提取工具

抖音视频无水印批量采集拓客软件助力高效营销&#xff01; 随着抖音平台的崛起&#xff0c;视频已成为各行各业进行营销的重要工具。但是&#xff0c;传统的视频下载方式往往效率低下&#xff0c;无法满足快速获取大量视频的需求。针对这一问题&#xff0c;我们开发了一款视频无…