Starrocks的CBO基石--統計信息的來源 StatisticAutoCollector

背景

本文來從底層代碼的實現來分析一下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分鐘)

    @Overrideprotected void runAfterCatalogReady() {// update intervalif (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 stateif (!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 priorityif (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_statisticsWHERE table_id = $tableId  and partition_id =  $partitionIdGROUP 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_statisticsWHERE 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])
    

以上都會觸發統計信息的收集。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/82012.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/82012.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/82012.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

深度學習模型部署(四)——RKNN

一、RKNN部署及工具包安裝 參考1&#xff1a;https://blog.csdn.net/qq_40280673/article/details/136211086#/ 參考2&#xff1a;瑞芯微官方教程 RKNN部署針對瑞芯微芯片優化&#xff0c;支持NPU硬件加速&#xff0c;需要安裝rknn-toolkit&#xff0c;用于將pytorch模型轉換為…

重構研發效能:項目管理引領軟件工廠邁向智能化

1.項目管理智能化&#xff0c;激活軟件工廠新引擎 在高速發展的軟件開發時代&#xff0c;企業如何高效管理多個項目、協調團隊合作、優化資源配置&#xff0c;已成為推動技術進步的關鍵。尤其是在多任務、多項目并行的復雜環境下&#xff0c;智能項目組合管理工具正成為軟件工…

小米汽車二期工廠下月將竣工,產能提升助力市場拓展

在新能源汽車市場競爭日益激烈的當下&#xff0c;小米汽車傳來重要進展消息。據多方信息顯示&#xff0c;小米汽車二期工廠下月即將竣工&#xff0c;這一關鍵節點的到來&#xff0c;有望為小米汽車的產能提升與市場布局帶來重大突破。? 小米汽車二期工廠位于北京亦莊&#xff…

Python 爬蟲實戰:電競比賽直播數據實時抓取與可視化分析

一、引言 在電競行業快速發展的今天,電競比賽直播數據成為了電競愛好者、分析師和商業機構關注的焦點。實時抓取電競比賽直播數據并進行分析,不僅可以幫助觀眾更好地理解比賽,還能為戰隊戰術優化、選手表現評估以及賽事運營提供重要參考。 本文將詳細介紹如何使用Python爬…

零基礎設計模式——創建型模式 - 生成器模式

第二部分&#xff1a;創建型模式 - 生成器模式 (Builder Pattern) 前面我們學習了單例、工廠方法和抽象工廠模式&#xff0c;它們都關注如何創建對象。生成器模式&#xff08;也常被稱為建造者模式&#xff09;是另一種創建型模式&#xff0c;它專注于將一個復雜對象的構建過程…

Debezium快照事件監聽器系統設計

Debezium快照事件監聽器系統設計 1. 系統概述 1.1 設計目標 為 Debezium 的快照過程提供可擴展的事件監聽機制允許外部系統在快照過程中執行自定義邏輯提供線程安全的事件分發機制確保監聽器的異常不會影響主快照流程1.2 核心功能 表快照開始事件監聽表快照完成事件監聽行數據…

手術機器人行業新趨勢:Kinova多機械臂協同系統如何突破復雜場景適應性瓶頸?

機器人手術歷經多階段技術演進&#xff0c;已成為現代醫療重要方向。其需求增長源于醫療機構對高精度低風險手術方案的需求、微創手術普及及技術進步帶來的復雜場景適應性提升。Kinova 輕型機械臂憑借模塊化設計與即插即用功能&#xff0c;可快速適配不同手術環境&#xff0c;為…

力扣面試150題-- 二叉樹展開為鏈表

Day 46 題目描述 思路 初次做法&#xff1a;由于我直接考慮O&#xff08;1&#xff09;級別的空間復雜度&#xff0c;于是采取了以下做法&#xff1a; 接下來的內容就是遞歸函數如果該節點為空&#xff0c;就返回null將此時的current作為頭節點&#xff0c;left和right作為孩…

【Python】開發工具uv

文章目錄 1. uv install1.1 下載安裝腳本來安裝1.2 使用pipx安裝uv1.3 補充 2. 考慮在離線系統上安裝uv2.1 下載并上傳安裝包2.2 用戶級安裝uv&#xff08;~/.local/bin/&#xff09;2.3 補充 3. uv 管理Python解釋器4. uv 管理依賴5. uv運行代碼5.1 uv不在項目下執行腳本5.2 u…

zabbix批量主機維護腳本兼容性更新

最近做新老版本zabbix監控主機遷移發現zabbix6.0后api安全有了效大升級&#xff0c;批量主機維護腳本出現認證兼容性問題&#xff0c;以下為腳本更新token支持&#xff1a;在這里插入代碼片&#xff1a; # /usr/bin/env python3 # -*- coding:utf-8 -*- import requests impor…

Java中static關鍵字深度解析:從入門到高階實戰

Java中static關鍵字深度解析&#xff1a;從入門到高階實戰 目錄 static的本質與核心特性靜態變量 vs 實例變量&#xff1a;底層對比靜態方法的設計哲學與應用場景高級用法&#xff1a;突破常規的static技巧 4.1 靜態代碼塊&#xff1a;類加載的“初始化引擎”4.2 靜態內部類&…

基于RT-Thread的STM32F4開發第五講——軟件模擬I2C

文章目錄 前言一、RT-Thread工程創建二、AT24C02三、函數編寫1.I2C_soft.c2.I2C_soft.h3.main.h 四、效果展示五、資源分享總結 前言 本章是基于RT-Thread studio實現軟件模擬I2C&#xff0c;開發板是正點原子的STM32F4探索者&#xff0c;使用的RT-Thread驅動是5.1.0&#xff0…

49、c# 能?foreach 遍歷訪問的對象需滿足什么條件?

在 C# 中&#xff0c;要使用 foreach 循環遍歷一個對象&#xff0c;該對象必須滿足以下條件之一&#xff1a; 1. 實現 IEnumerable 或 IEnumerable 接口 非泛型版本&#xff1a;System.Collections.IEnumerable public class MyCollection : IEnumerable {private int[] _da…

推客小程序系統開發:全棧式技術解決方案與行業賦能實踐?

? 在數字化營銷深度滲透各行業的當下&#xff0c;傳統推廣模式已難以滿足企業精細化運營與高效獲客的需求。專業的推客小程序系統憑借其強大的裂變傳播能力與靈活的推廣機制&#xff0c;成為企業構建私域流量池、提升推廣效能的核心工具。我們基于多年技術沉淀與行業洞察&…

WPF布局系統詳解:掌握界面設計的核心藝術

掌握界面設計的核心藝術 1. WPF布局系統概述2. Grid布局詳解2.1 基本行列定義2.2 單元格定位與跨行跨列 3. StackPanel布局4. DockPanel布局5. WrapPanel與Canvas5.1 WrapPanel自動換行布局 5. Canvas絕對定位6. 布局嵌套與綜合應用7. 布局性能優化8. 響應式布局技巧9. 實戰&am…

labview實現LED流水燈的第一種方法

目的&#xff1a;寫一個跑馬燈程序&#xff0c;7個燈從左到右不停的輪流點亮&#xff0c;閃爍間隔由滑動條調節。 一、方法1&#xff1a;使用順序結構 使用順序結構&#xff0c;平鋪式順序結構與創建局部變量實現LED流水燈 具體步驟如下&#xff1a; 第一步&#xff0c;選擇…

uniapp如何設置uni.request可變請求ip地址

文章目錄 簡介方法一&#xff1a;直接在請求URL中嵌入變量方法二&#xff1a;使用全局變量方法三&#xff1a;使用環境變量方法四&#xff1a;服務端配置方法五&#xff1a;使用配置文件&#xff08;如config.js&#xff09;:總結 簡介 在uni-app中&#xff0c;uni.request 用…

深度學習篇---LSTMADF軌跡預測

文章目錄 前言LSTM 軌跡預測原理應用在行人軌跡預測方面在自動駕駛車輛的軌跡預測中優點缺點APF 軌跡預測原理應用在船舶運動規劃在無人駕駛車輛避障軌跡跟蹤優點缺點示例代碼前言 本文簡單介紹LSTM(長短期記憶網絡)和ADF(人工勢場法)這兩種不同的軌跡預測方法。 LSTM 軌跡…

python實現Web請求與響應

目錄 一&#xff1a;什么是Web請求與響應&#xff1f; 1&#xff1a;Web請求 2&#xff1a;Web響應 3&#xff1a;HTTP協議概述 4&#xff1a;常見的HTTP狀態碼包括&#xff1a; 二&#xff1a;python的requests庫 1&#xff1a;安裝requests庫 2&#xff1a;發送GET請…

Unity使用sherpa-onnx實現說話人識別

網友軟綿綿的面包人推薦&#xff0c;模型3dspeaker_speech_eres2net_base_200k_sv_zh-cn_16k-common.onnx的效果比3dspeaker_speech_eres2net_base_sv_zh-cn_3dspeaker_16k.onnx要好 具體代碼 using System; using System.Collections.Generic; using System.IO; using Sherpa…