Starrocks的CBO基石--统计信息的来源 StatisticAutoCollector

JSP期末考试复习习题及答案 以下习题是对于平时课堂小测的整理,如有错误敬请指正! 欢迎一起交流~ 预祝各位小伙伴们考试顺利! Test1 一. 单选题 – 1.(单选题)当用户请求jsp页面时,JSP引擎就会执行该页面的字节码文件响应客户的请求,执行字节码文件的结果是() A. 发送一个JSP源文件到客户端 B. 发送一个Java文件到客户端 C. 发送一个HTML页面到客户端 D. 什么都不做 – 2.(单选题)下列动态网页和静态网页的根本区别描述错误的是( D) A. 静态网页服务器端返回的HTML文件是事先存储好的 B. 动. 阅读详情

背景

本文来从底层代码的实现来分析一下Starrocks怎么获取统计信息,这些统计信息在后续基于CBO的代价计算的时候有着重要的作用
本文基于Starrrocks 3.3.5

结论

Starrocks的统计信息的收集是通过周期性的运行一系列的SQL(以分区为维度,如果不是分区表,其实也有个默认的分区,也就是单个分区),之后插入到_statistics_.column_statistics表中,并会存储在 GlobalStateMgr.CachedStatisticStorage,后续所有的统计信息的获取也是通过这里获取的

分析

直接到StatisticAutoCollector类

    public StatisticAutoCollector() {
        super("AutoStatistic", Config.statistic_collect_interval_sec * 1000);
    }

这里默认的调度周期是 statistic_collect_interval_sec (也就是5分钟)

    @Override
    protected void runAfterCatalogReady() {
        // update interval
        if (getInterval() != Config.statistic_collect_interval_sec * 1000) {
            setInterval(Config.statistic_collect_interval_sec * 1000);
        }

        if (!Config.enable_statistic_collect || FeConstants.runningUnitTest) {
            return;
        }

        if (!checkoutAnalyzeTime(LocalTime.now(TimeUtils.getTimeZone().toZoneId()))) {
            return;
        }

        // check statistic table state
        if (!StatisticUtils.checkStatisticTableStateNormal()) {
            return;
        }

        initDefaultJob();

        runJobs();
    }

  • 强制 调度周期设置为5分钟
  • 进行 调度时间的检查,默认是一天,也可以设置开始和结束时间,statistic_auto_analyze_start_time,statistic_auto_analyze_end_time
  • 还可以设置enable_statistic_collect为false,如果不想进行统计信息的采集的话
  • initDefaultJob 初始化统计信息采集任务,默认是 enable_collect_full_statistic 为 true,也就是全量采集
  • runJobs 运行采集任务,也就是最核心的阶段
         protected List<StatisticsCollectJob> runJobs() {
    
          ...
          Set<Long> analyzeTableSet = Sets.newHashSet();
    
          for (NativeAnalyzeJob nativeAnalyzeJob : allNativeAnalyzeJobs) {
              List<StatisticsCollectJob> jobs = nativeAnalyzeJob.instantiateJobs();
              result.addAll(jobs);
              ConnectContext statsConnectCtx = StatisticUtils.buildConnectContext();
              statsConnectCtx.setThreadLocalInfo();
              nativeAnalyzeJob.run(statsConnectCtx, STATISTIC_EXECUTOR, jobs);
    
              for (StatisticsCollectJob job : jobs) {
                  if (job.isAnalyzeTable()) {
                      analyzeTableSet.add(job.getTable().getId());
                  }
              }
          }
          LOG.info("auto collect statistic on analyze job[{}] end", analyzeJobIds);
    
          if (Config.enable_collect_full_statistic) {
              LOG.info("auto collect full statistic on all databases start");
              List<StatisticsCollectJob> allJobs =
                      StatisticsCollectJobFactory.buildStatisticsCollectJob(createDefaultJobAnalyzeAll());
              for (StatisticsCollectJob statsJob : allJobs) {
                  // user-created analyze job has a higher priority
                  if (statsJob.isAnalyzeTable() && analyzeTableSet.contains(statsJob.getTable().getId())) {
                      continue;
                  }
    
                  result.add(statsJob);
                  AnalyzeStatus analyzeStatus = new NativeAnalyzeStatus(GlobalStateMgr.getCurrentState().getNextId(),
                          statsJob.getDb().getId(), statsJob.getTable().getId(), statsJob.getColumnNames(),
                          statsJob.getType(), statsJob.getScheduleType(), statsJob.getProperties(), LocalDateTime.now());
                  analyzeStatus.setStatus(StatsConstants.ScheduleStatus.FAILED);
                  GlobalStateMgr.getCurrentState().getAnalyzeMgr().addAnalyzeStatus(analyzeStatus);
    
                  ConnectContext statsConnectCtx = StatisticUtils.buildConnectContext();
                  statsConnectCtx.setThreadLocalInfo();
                  STATISTIC_EXECUTOR.collectStatistics(statsConnectCtx, statsJob, analyzeStatus, true);
              }
              LOG.info("auto collect full statistic on all databases end");
          }
    
          ...
    
          return result;
      }
    
    
    • nativeAnalyzeJob.instantiateJobs 构造统计信息
      这里调用了StatisticsCollectJobFactory.buildStatisticsCollectJob 方法,
      首先这里有个配置 statistic_exclude_pattern可以排除不需要进行统计的表(以db.table格式)
      其次是会根据当前所谓的健康度(也就是分区更新的时间比例)和statistic_auto_collect_ratio大小比较,如果健康度小于该值,则调用createFullStatsJob方法,创建全量统计任务。
      这里 主要用 buildStatisticsCollectJob 构造一个FullStatisticsCollectJob类型的job
    • nativeAnalyzeJob.run 运行统计信息任务
      这个方法会调用StatisticExecutor.collectStatistics,最终会调用FullStatisticsCollectJob.collect方法
       int parallelism = Math.max(1, context.getSessionVariable().getStatisticCollectParallelism());
         List<List<String>> collectSQLList = buildCollectSQLList(parallelism);
         long totalCollectSQL = collectSQLList.size();
         ...
         Exception lastFailure = null;
         for (List<String> sqlUnion : collectSQLList) {
             if (sqlUnion.size() < parallelism) {
                 context.getSessionVariable().setPipelineDop(parallelism / sqlUnion.size());
             } else {
                 context.getSessionVariable().setPipelineDop(1);
             }
      
             String sql = Joiner.on(" UNION ALL ").join(sqlUnion);
      
             try {
                 collectStatisticSync(sql, context);
             } catch (Exception e) {
                 ...
             }
             finishedSQLNum++;
             analyzeStatus.setProgress(finishedSQLNum * 100 / totalCollectSQL);
             GlobalStateMgr.getCurrentState().getAnalyzeMgr().addAnalyzeStatus(analyzeStatus);
         }
         ...
         flushInsertStatisticsData(context, true);
      
      
      • 首先设置一个 运行sql的并行度statistic_collect_parallel默认是1,这个意思就是这个统计sql会分多少次运行
      • buildCollectSQLList 这里会构建具体运行统计信息的SQL,这会具体的分区级别
      • collectStatisticSync 这里会执行具体的SQL
        SQL如下:
         SELECT cast(4 as INT) ,
            cast($partitionId as BIGINT) ,
            '$columnNameStr' ,
            cast(COUNT(1) as BIGINT) ,
            cast($dataSize as BIGINT) ,
            hex(hll_serialize(IFNULL(hll_raw(column_key), hll_empty()))),
            cast( (COUNT(1) - COUNT(column_key)) as BIGINT) ,
            MAX(column_key) ,
            MIN(column_key) 
            FROM (select $quoteColumnName as column_key from `$dbName`.`$tableName` partition `$partitionName`) tt
        
      • flushInsertStatisticsData 这里会把执行的结果数据存储到_statistics_.column_statistics
    • analyzeMgr.refreshBasicStatisticsCache 这个主要的作用是 更新CachedStatisticStorage 里的统计信息
      主要通过 refreshTableStatistic 和 getColumnStatistics
      这两个方法分别会调用 TableStatsCacheLoader 和 ColumnBasicStatsCacheLoader 去执行SQL从而获取对应的统计信息,调用的SQL如下:
        select cast(3 as INT), partition_id, any_value(row_count)
                      FROM  column_statistics
                      WHERE table_id = $tableId  and partition_id =  $partitionId
                      GROUP BY partition_id;
      
        SELECT cast( 1  as INT), $updateTime, db_id, table_id, column_name,
                     sum(row_count), cast(sum(data_size) as bigint), hll_union_agg(ndv), sum(null_count), 
                     cast(max(cast(max as $type)) as string), cast(min(cast(min as $type)) as string)
                     FROM   column_statistics
                     WHERE table_id = $table_id and column_name in (xxx,xxx,xxx)
                     GROUP BY db_id, table_id, column_name;
      

其他

  • StatisticAutoCollector 是通过周期性的任务来进行统计信息的收集
  • 手动的收集
    ANALYZE TABLE
    如命令:
    ANALYZE [FULL|SAMPLE] TABLE tbl_name (col_name [,col_name])
    [WITH SYNC | ASYNC MODE]
    PROPERTIES (property [,property])
    
  • 手动触发自动收集
    CREATE ANALYZE
    如命令:
    CREATE ANALYZE [FULL|SAMPLE] TABLE tbl_name (col_name [,col_name])
    PROPERTIES (property [,property])
    

以上都会触发统计信息的收集。

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况 主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。 立即下载

相关推荐

ESP8266连接阿里云(STM32)

一、概述 之前通过串口调试助手+ESP8266已经连接上阿里云了 ESP8266连接阿里云(串口调试助手) 这次我们使用STM32+ESP8266来接入阿里云,其实本质上就是STM32和ESP8266进行串口通信,相当于使用STM32代替之前使用的串口调试助手来发送AT指令。只是发送的字符串数据可能有些细节需要注意一下。 二、保存连接的AT指令 定义几个字符串数据保存需要发送的AT指令 //注意: //末尾记得加\r\n //字符...

xyx0610的博客 4万+

StarRocks 统计信息和 Cost 估算

在本文我们介绍了如何通过 Analyze 任务来收集统计信息,如何自底向上地计算各个节点的统计信息,也介绍了 Optimizer 是如何使用 Memo 计算 Cost,以及是如何在 Plan 的探索过程中利用 Cost Upper Bound 进行裁剪,并最终选择出代价最小的 Plan。

StarRocks的博客 1498

论文阅读—Square Attack: a query-efficient black-box adversarial attack via random search

论文阅读—Square Attack: a query-efficient black-box adversarial attack via random search 发表位置 ECCV 2020 摘要 作者提出了一种基于得分的黑盒Square attack,该模型不依赖于模型的局部梯度信息,因此可以绕过梯度隐藏防御攻击。Square Attack是一种随机搜索方法,它在随机位置选择局部的方形更新,使得每次迭代时扰动近似位于可行集的边界。 背景 当涉及到对安全至关重要的机器学习应用时,对抗性的例子尤其值得

yayayamaomaoya的博客 2492

Spark DPP(动态分区裁剪)导致的DataSourceScanExec NullPointerException问题分析以及解决

背景 本文基于spark 3.1.2,且运行在yarn模式下 最近在调试 spark sql的时候遇到了空指针的问题,如下: Caused by: java.lang.NullPointerException at org.apache.spark.sql.execution.DataSourceScanExec.$init$(DataSourceScanExec.scala:57) at org.apache.spark.sql.execution.FileSourceScanExec.<in

monkeyboy_tech的博客 3万+

全桥LLC谐振变换器变频控制工作原理与仿真

全桥LLC谐振变换器以其效率高、全范围软开关、器件电应力小等优点,越来越多地应用于大功率场合。电力电子技术的发展日益追求高频化,所带来的问题是半导体开关器件高频运行时的开关损耗急剧增加。各种软开关电路随之出现。可以有效减小开关损耗,使进一步提高开关频率成为可能。谐振式开关因其可在电流自然过零点开通半导体器件,实现零电压开关,特别适合采用MOSFET作开关的装置。最简单的谐振电路有串联谐振(SRC)和并联谐振(PRC)。SRC只能工作于降压状态,应用受限;

晞子的技术札记 3060

100天精通Python(基础篇)——第3天:运算符全解析(算术运算符、比较运算符、逻辑运算符、赋值运算符及其优先级规则)

100天精通Python(基础篇)——第3天:运算符全解析(算术运算符、比较运算符、逻辑运算符、赋值运算符及其优先级规则)

努力让自己发光,对的人才能迎着光而来 14万+

SPARK SQL中 CTE(with表达式)会影响性能么?

背景及问题 本文基于spark 3.1.2 最近在排查spark sql问题的时候,出现了一系列的(CTE)with操作,导致该任务运行不出来,而把对应的(CTE)with 替换成了临时表以后,任务很快的就能运行出来 对应的最简化的sql如下: with temp1 as ( select null as user_id ,a.sku_id ,int(sum(`可申请数量`)) `开放申请数量` from xxx.xxx `a` where pt between '20

monkeyboy_tech的博客 7321

ubuntu22.04下对使用linuxdeployqt发布的qt程序进行deb打包操作

【代码】ubuntu22.04下对使用linuxdeployqt发布的qt程序进行deb打包操作。

十三阿哥的博客 1401

Spark task过多导致任务运行过慢甚至超时

背景以及现象 本文基于 spark 3.1.2 设置spark.driver.memory=2g 在调试spark sql任务的时候,发现有几个任务产生了40多万个Task,而且任务长期运行不出来。 分析 运行此sql,可以得到如下的dag(我们只截取产生Task多的Stage),由此可以看到是scan的文件太大了(scan了日志文件半年的数据)。 但是为什么这种情况下会导致任务运行很缓慢甚至会超时呢? 找到driver端, 用jstat -gcutil查看一下对应的gc情况(对应的内存都是调优完后的镜像

monkeyboy_tech的博客 6799

喷涂机器人系列编程:ABB IRB 5500_(7).喷涂质量控制与优化

通过编程手段对ABB IRB 5500喷涂机器人进行质量控制和优化,可以显著提高喷涂的均匀性和附着力,减少涂层缺陷。具体的方法包括喷涂参数的调整、路径规划的优化、喷涂效果的检测与反馈,以及喷涂参数的动态调整。综合评估系统可以进一步确保喷涂质量的稳定性和一致性,帮助汽车制造企业提高产品质量和生产效率。

zhubeibei168的博客 851

YOLOv12改进专栏目录 | 本专栏持续更新500+篇内容 | 包含各种卷积、主干网络、各种注意力机制、检测头、损失函数、小目标检测改进、二次创新模块、独家创新等几百种创新点改进

《YOLOv12高效涨点改进专栏》提供500+创新改进方案,涵盖卷积、主干网络、注意力机制等模块优化,适用于检测、分割等任务。改进点来自顶会论文和个人经验,支持多种模型版本和任务场景。专栏包含详细教程、数据集增强、性能评估工具等,帮助科研人员快速实现模型优化和论文发表。提供完整运行项目和环境配置指导,适合计算机及相关专业研究人员使用,持续更新保障长期科研需求。

Ai缝合怪、助力小伙伴高效发论文 2300

【k8s系列5】KubernetesClientException: too old resource version 原因分析

背景 公司目前在基于k8s做调度(基于io.fabric8:kubernetes-client:4.2.0),在运行的过程中,遇到了如下问题: OkHttp WebSocket https://10.25.61.82:6443/...] DEBUG io.fabric8.kubernetes.client.dsl.internal.WatchConnectionManager - WebSocket close received. code: 1000, reason: [OkHttp WebSocket

monkeyboy_tech的博客 6040

抖音 webmssdk 签名算法解析:X-Dynosaur / X-Gnarly / X-Bogus 生成原理

它只依赖设备指纹/环境编码与随机数,与 query 内容无关,因此可以独立于 Dynosaur/Gnarly 生成。

猫敷雪 197

【mlflow系列1】mlflow 的搭建使用

背景 mlflow是Databrick开源的机器学习管理平台,它很好的解藕了算法训练和算法模型服务,使得算法工程师专注于模型的训练,而不需要过多的关注于服务的, 而且在我们公司已经有十多个服务稳定运行了两年多。 搭建 mlflow的搭建主要是mlflow tracking server的搭建,tracking server主要是用于模型的元数据以及模型的数据存储 我们这次以minio作为模型数据的存储后台,mysql作为模型元数据的存储,因为这种模式能满足线上的需求,不仅仅是用于测试 minio的搭建

monkeyboy_tech的博客 5183

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

【spark系列12】spark remote shuffle service(RSS)杂谈

背景 对于spark shuffle service(以下简称RSS),在社区其实早就有探讨SPARK-25299,只不过一直没有达成一致,且目前的内置的shuffle service 也能满足大部分的场景,也就被搁置了,但是由于kubernetes的越来越火热,spark 社区也慢慢的集成了spark on k8s,当然k8s社区也集成了spark,具体区别见spark on k8s 与 spark on k8s operator的对比. 但是就目前的spark on k8s来说shuffle还是存在问题

monkeyboy_tech的博客 4859

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

FLINK JDBC SQL Connector遇到的类型转换问题

背景 Flink 1.3 最近在写Flink Sql的时候,遇到了java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long 问题 分析 直接上报错的sql,如下: CREATE TABLE `xxx` ( `merchantId` BIGINT, `userId` BIGINT, `status` BIGINT ) WITH ( ); 具体的问题堆栈如下: java.lang.C

monkeyboy_tech的博客 4840

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

SPARK的计算向量化-已有的向量化项目

背景 在SPARK的计算向量化-spark本身的向量化中,我们提到spark是利用代码生成(生成for循环),从而JIT进行向量化。这是有局限的,所以大部分公司都会采用通过其他方式来进行向量化计算。 我们列举几种已知的应用到spark计算引擎的向量化技术。 Velox Meta(也就是Facebook)开源的一个C++实现的SQL执行引擎,输入逻辑执行计划,利用SIMD指令实现向量化操作,输出结果; 结合Apache Arrow作数据交换,可以实现Spark的计算向量化。 项目见facebookincuba

monkeyboy_tech的博客 4315

yarn和k8s(kubernetes)混合部署初步方案(利用cgroup资源限制)

版本 yarn 2.6.0 k8s v1.15.2 背景 随着k8s的越来越火热以及k8s的可扩展以及自修复优势,k8s势必是互联网的优势,但是很大一部分公司的资源管理工具依旧是yarn,而且yarn和k8s也必然并行很久一段时间, 但是由于yarn的隔离型相对于k8s来说还是很弱的,好在yarn 2.6.0版本也集成了LinuxContainerExecutor(默认是DefaultContainerExecutor),也就是说yarn在好长一段时间是不支持cpu限制的,LinuxContainerExe

monkeyboy_tech的博客 4158

SPARK Expand问题的解决(由count distinct、group sets、cube、rollup引起的)

背景 本文基于spark 3.1.2 我们知道spark对于count(distinct)/group sets 以及cube、rollup的处理都是采用转换为Expand的方法处理, 这样做的优点就是在数据量小的情况下,能有以空间换时间,从而达到加速的目的。 但是弊端也是很明显,就是在数据量较大的情况下,而且expand的倍数达到上百倍或者千倍的时候,这任务运行的时间很长(这在数分中是非常常见的)。 分析 先来看一组图: 是不是很刺激,数据从2,635,978,109直接扩张到了168,702,598,

monkeyboy_tech的博客 4010

SPARK 是怎么清除Shuffle中间结果数据的

背景 本文基于 SPARK 3.2.1 我们知道在Spark中,shuffle的数据会存在ESS或者BlockManager中的,但是spark什么时候会删除shuffle的中间结果数据呢?这篇文章我们来分析一下 分析 我们知道spark肯定会删除shuffle结果数据,要不然长期以往,磁盘肯定会爆掉。 其中清除的组件就是ContextCleaner,代码如下: private[spark] class ContextCleaner( sc: SparkContext, shuffleDri

monkeyboy_tech的博客 3839

Spark做TPC-DS性能测试

最近由于在做上云的工作,并且公司离线部分引擎是Spark,所以做了一次基于TPC-DS性能比对测试。生产了大约200GB的数据。

monkeyboy_tech的博客 3701

Spark中的WholeStageCodegenExec(全代码生成)

背景 在之前的文章中Spark DPP(动态分区裁剪)导致的DataSourceScanExec NullPointerException问题分析以及解决,我们直接跳过了动态代码生成失败这版本一步部分,这次我们来分析一下,SQL还是在以上提到的文章中。 分析 运行完该sql,我们可以看到如下的物理计划: 我们看到FilterExec和ColumnarRoRowExec并没有在一个WholeStageCodegen 中, 这是为什么呢? 这是因为exists方法是继承自CodegenFallback Tr

monkeyboy_tech的博客 3466

Spark CTAS union all (union all的个数很多)导致超过spark.driver.maxResultSize配置(1G)

spark CTAS nuion all (union all的个数很多)导致超过spark.driver.maxResultSize配置(2G)

monkeyboy_tech的博客 3041

深入理解SPARK SQL 中HashAggregateExec和ObjectHashAggregateExec以及UnsafeRow

感悟和理解 翻译这篇文章是为了更好的理解ObjectHashAggregateExec和UnsafeRow,关于UnsafeRow的文章,可以参考Spark源码修改系列 - UnsafeRow内存布局和代码优化。 其实明显,UnsafeRow是模拟了offheap的分配方式而在堆上进行的操作,它并没有脱离了jvm,而是使用了Java unsafe API(Java提供的底层非安全操作接口),允许用户像操作C++指针一样来申请和访问内存地址,JVM也不会对这部分非安全数据进行额外的类型检查和垃圾回收。 事实上

monkeyboy_tech的博客 2960

Flink 学习日志 03:自定义一个SourceFunction,完成对Redis中数据的读取

本文介绍了在Flink中自定义SourceFunction读取Redis数据的完整流程:通过Jedis客户端连接WSL2中的Redis服务,编写RedisSource实现循环读取所有Key-value并逐条输出,结合Thread.sleep()实现每秒一条的流式效果。关键步骤包括环境准备、添加Jedis依赖、配置IDEA运行时加载provided依赖,并注意生产环境中应避免使用阻塞的keys *,改用scan命令。最终实现动态读取、实时打印,验证了Flink与Redis的数据集成能力。

木木的学习笔记 401

Elasticsearch ingest pipeline 被禁用之后:性能代价、安全治理与数据入库时间的四种替代方案

生产环境为什么禁用 Elasticsearch ingest pipeline?写入路径同步执行的开销、Painless 脚本的安全治理是根因;而 _ingest.timestamp 出不了 pipeline,ES 8/9 也没有原生入库时间字段。本文给出四种替代方案:采集端注入时间戳、bulk 响应后回写、refresh=wait_for 近似、最小 set pipeline 白名单,附选型对比与踩坑清单。

Sayai的专栏 339
上一篇: Starrocks的主键表涉及到的MOR Delete+Insert更新策略
下一篇: Starrocks 怎么计算各个算子的统计信息
鸿乃江边鸟
博客等级 码龄6年 3746粉丝 235原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值