StarRocks 中 CURRENT_TIMESTAMP 和 current_time 分區過濾問題

背景

本文基于Starrocks 3.3.5
最近在進行Starrocks 跑數據的時候,發現了一個SQL 掃描了所有分區的數據,簡化后的SQL如下:

select date_created from tableA where date_created=date_format(current_time(), '%Y-%m-%d %H:%i:%S') limit 20

其中建表語句如下:

CREATE TABLE `tableA` (...`date_created` datetime NOT NULL DEFAULT "1970-01-01 00:00:00" COMMENT "",...
) ENGINE=OLAP
PRIMARY KEY(id,date_created)
PARTITION BY date_trunc("day",date_created)
DISTRIBUTED BY HASH(id) BUCKETS 50
PROPERTIES( "compression" = "ZSTD");

但是如果用CURRENT_TIMESTAMP 替換的話,就能實現分區下推,具體的SQL如下:

select date_created from tableA where date_created=CURRENT_TIMESTAMP() limit 20

結論

current_time() 函數不支持常量折疊,也就是不支持在計劃解析和優化階段來計算結果。而CURRENT_TIMESTAMP 在計劃優化階段就可以計算出結果。
具體的explain對應的SQL如下:
在這里插入圖片描述
在這里插入圖片描述

可以看到 用 current_time 函數的 掃描了全部的分區
CURRENT_TIMESTAMP函數的 只選擇了一個分區的數據

分析

先執行兩個命令從感官上來感受一下:

TRACE LOGS OPTIMIZER  SELECT CURRENT_TIMESTAMP()\G;
TRACE LOGS OPTIMIZER  SELECT (date_format(current_time(), '%Y-%m-%d %H:%i:%S'))\G;

TRACE LOGS OPTIMIZER SELECT CURRENT_TIMESTAMP()\G;`的結果如下:

...
*************************** 34. row ***************************
Explain String: 0ms|    [MV TRACE] [PREPARE GLOBAL] There are no valid related mvs for the query plan
*************************** 35. row ***************************
Explain String: 0ms|    [MV TRACE] [PREPARE GLOBAL] MV rewrite strategy: MvRewriteStrategy{enableMaterializedViewRewrite=false, enableForceRBORewrite=false, enableViewBasedRewrite=false, enableSingleTableRewrite=false, enableMultiTableRewrite=false, mvStrategy=DEFAULT}
*************************** 36. row ***************************
Explain String: 0ms|    origin logicOperatorTree:
*************************** 37. row ***************************
Explain String: LogicalProjectOperator {projection=[2025-03-28 10:35:00]}
*************************** 38. row ***************************
Explain String: ->  LOGICAL_VALUES
*************************** 39. row ***************************
Explain String: 0ms|    [TRACE QUERY 3efdbff0-0b7d-11f0-8f6c-00163e164034] APPLY RULE TF_PRUNE_PROJECT_COLUMNS 58
*************************** 40. row ***************************
Explain String: Original Expression:
*************************** 41. row ***************************
Explain String: LogicalProjectOperator {projection=[2025-03-28 10:35:00]}
*************************** 42. row ***************************
Explain String: ->  LOGICAL_VALUES
*************************** 43. row ***************************
Explain String: 0ms|
*************************** 44. row ***************************
Explain String: New Expression:
*************************** 45. row ***************************
Explain String: 0:LogicalProjectOperator {projection=[2025-03-28 10:35:00]}
...

TRACE LOGS OPTIMIZER SELECT (date_format(current_time(), '%Y-%m-%d %H:%i:%S'))\G的結果如下:

...
*************************** 34. row ***************************
Explain String: 0ms|    [MV TRACE] [PREPARE GLOBAL] MV rewrite strategy: MvRewriteStrategy{enableMaterializedViewRewrite=false, enableForceRBORewrite=false, enableViewBasedRewrite=false, enableSingleTableRewrite=false, enableMultiTableRewrite=false, mvStrategy=DEFAULT}
*************************** 35. row ***************************
Explain String: 0ms|    origin logicOperatorTree:
*************************** 36. row ***************************
Explain String: LogicalProjectOperator {projection=[date_format(cast(current_time() as datetime), %Y-%m-%d %H:%i:%S)]}
*************************** 37. row ***************************
Explain String: ->  LOGICAL_VALUES
*************************** 38. row ***************************
Explain String: 0ms|    [TRACE QUERY 7af2e9bb-0b7e-11f0-8f6c-00163e164034] APPLY RULE TF_PRUNE_PROJECT_COLUMNS 58
*************************** 39. row ***************************
Explain String: Original Expression:
*************************** 40. row ***************************
Explain String: LogicalProjectOperator {projection=[date_format(cast(current_time() as datetime), %Y-%m-%d %H:%i:%S)]}
*************************** 41. row ***************************
Explain String: ->  LOGICAL_VALUES
*************************** 42. row ***************************
Explain String: 0ms|
*************************** 43. row ***************************
Explain String: New Expression:
*************************** 44. row ***************************
Explain String: 0:LogicalProjectOperator {projection=[date_format(cast(current_time() as datetime), %Y-%m-%d %H:%i:%S)]}
*************************** 45. row ***************************
Explain String: ->  LOGICAL_VALUES
...

可以看到 CURRENT_TIMESTAMP 在優化算子階段就已經計算出來了,為LogicalProjectOperator {projection=[2025-03-28 10:35:00]}
(date_format(current_time(), '%Y-%m-%d %H:%i:%S')) 并沒有計算出來,為LogicalProjectOperator {projection=[date_format(cast(current_time() as datetime), %Y-%m-%d %H:%i:%S)]}

在這個案例中,主要涉及到的規則主要是:

FoldConstantsRule
PartitionPruneRule

我們分析一下簡單的SQL語句的數據流:SELECT CURRENT_TIMESTAMP()

g4文件中querySpecification||\/
ConnectProcessor.handleQuery||\/
com.starrocks.sql.parser.SqlParser.parse||\/
// 同時.g4 文件中 specialDateTimeExpression
// AstBuilder.visitSpecialDateTimeExpression 會構造 new FunctionCallExpr
// 這里最終會構建 SelectRelation(SelectList(FunctionCallExpr),ValuesRelation.newDualRelation)
AstBuilder.visitQuerySpecification ||\/
StatementPlanner.plan||\/
createQueryPlan||\/
new RelationTransformer(transformerContext).transformWithSelectLimit(query) ||\/
transform||\/
visit(relation);||\/
RelationTransformer.visitSelect||\/
QueryTransformer.plan||\/
SqlToScalarOperatorTranslator.translate => Visitor.visit => visitFunctionCall // 此時的邏輯計劃為 SelectRelation(SelectList(CallOperator(CURRENT_TIMESTAMP)),ValuesRelation.newDualRelation)||\/=> scalarRewriter.rewrite(result, ScalarOperatorRewriter.DEFAULT_REWRITE_RULES) // 這里有ImplicitCastRule和FoldConstantsRule||\/
projectForOrder  // 此時的的邏輯計劃為 LogicalPlan(OptExprBuilder(LogicalProjectOperator(CallOperator(CURRENT_TIMESTAMP)))

現在來重點關注 DEFAULT_REWRITE_RULES 中涉及到的 ImplicitCastRule FoldConstantsRule 規則:
首先是 ImplicitCastRule 規則(這里主要是visitCall方法):

這個規則主做:
1. 如果表達式需要的類型和該表達式對應的子表達式的參數輸出的類型如果不一致的話,則會給表達式的子表達式加上一個CastOperator操作
2. 對每一個子表達式都遞歸一遍1步驟

date_format(current_time(), '%Y-%m-%d %H:%i:%S')就會命中這個規則
再次 是 FoldConstantsRule 規則(這里主要是visitCall/visitCastOperator方法):

這個主要是做:
1. 主要是計算表達式為常量,即把CallOperator變成 ConstantOperator
2. 根據ScalarOperatorFunctions 和 MetaFunctions 函數中標注為 ConstantFunction 的函數,來看是否能夠計算為常量
在這里能夠找到  CURRENT_TIMESTAMP() 函數,但是找不到 current_time() 函數

CURRENT_TIMESTAMP() 就會命中這個規則

以上的 都在 “Transformer” 階段完成的。
至于 PartitionPruneRule 則會在“Optimizer” 階段完成 ,也就是optimizer.optimize方法中, 具體的實現,可以細看 PartitionPruneRule對應的方法,也就是在這個規則里會對涉及到的謂詞來過濾出對應的分區,很顯然因為CURRENT_TIMESTAMP是常量,所以能夠裁剪到對應的分區中去,而date_format(current_time(), '%Y-%m-%d %H:%i:%S')不能計算出來,所以掃描了全表。

其他

trace輸出信息的怎么回事

首先在g4文件中

queryStatement: (explainDesc | optimizerTrace) ? queryRelation outfile?;

有對應的optimze語句 也就是 TRACE LOGS
這個在解析的時候 AstBuilder.visitQueryStatement 中會調用 queryStatement.setIsTrace 方法:

public void setIsTrace(Tracers.Mode mode, String module) {this.isExplain = true;this.traceMode = mode;this.traceModule = module;}

此時 isExplain 設置為了true
之后在 StmtExecutor.execute方法中:

 } else if (parsedStmt.isExplain()) {String explainString = buildExplainString(execPlan, ResourceGroupClassifier.QueryType.SELECT,parsedStmt.getExplainLevel());if (executeInFe) {explainString = "EXECUTE IN FE\n" + explainString;}

這里的方法buildExplainString就會組裝對應的explain信息:

 if (parsedStmt.getTraceMode() == Tracers.Mode.TIMER) {explainString += Tracers.printScopeTimer();} else if (parsedStmt.getTraceMode() == Tracers.Mode.VARS) {explainString += Tracers.printVars();} else if (parsedStmt.getTraceMode() == Tracers.Mode.TIMING) {explainString += Tracers.printTiming();} else if (parsedStmt.getTraceMode() == Tracers.Mode.LOGS) {explainString += Tracers.printLogs();} else if (parsedStmt.getTraceMode() == Tracers.Mode.REASON) {explainString += Tracers.printReasons();} else {explainString += execPlan.getExplainString(explainLevel);}

所以在執行trace LOGS命令的時候會輸出對應信息

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

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

相關文章

從物理學到機器學習:用技術手段量化分析職場被動攻擊行為

從物理學到機器學習:用技術手段量化分析職場被動攻擊行為 1. 從物理系統視角看團隊協作 1.1 團隊系統的能量模型 在熱力學系統中,系統的總能量由動能和勢能組成。類比到團隊協作中,我們可以建立如下模型: class TeamEnergy:def __init__(self, members):self.kinetic = …

Pytroch搭建全連接神經網絡識別MNIST手寫數字數據集

編寫步驟 之前已經記錄國多次的編寫步驟了,無需多言。 (1)準備數據集 這里我們使用MNIST數據集,有官方下載渠道。我們直接使用torchvison里面提供的數據讀取功能包就行。如果不使用這個,自己像這樣子構建也一樣。 # …

Java 基本數據類型 vs 包裝類(引用數據類型)

一、核心概念對比(以 int vs Integer 為例) 特性基本數據類型(int)包裝類(Integer)數據類型原始值(Primitive Value)對象(Object)默認值0null內存位置棧&…

什么是 強化學習(RL):以DQN、PPO等經典模型

什么是 強化學習(RL):以DQN、PPO等經典模型 DQN(深度 Q 網絡)和 PPO(近端策略優化)共同屬于強化學習(Reinforcement Learning,RL)這一領域。強化學習是機器學習中的一個重要分支,其核心在于智能體(Agent)通過與環境進行交互,根據環境反饋的獎勵信號來學習最優的…

【Sql Server】在SQL Server中生成雪花ID(Snowflake ID)

大家好,我是全棧小5,歡迎來到《小5講堂》。 這是《Sql Server》系列文章,每篇文章將以博主理解的角度展開講解。 溫馨提示:博主能力有限,理解水平有限,若有不對之處望指正! 目錄 前言認識雪花ID…

HTML 表單處理進階:驗證與提交機制的學習心得與進度(一)

引言 在前端開發的廣袤領域中,HTML 表單處理堪稱基石般的存在,是構建交互性 Web 應用不可或缺的關鍵環節。從日常頻繁使用的登錄注冊表單,到功能多樣的搜索欄、反饋表單,HTML 表單如同橋梁,緊密連接著用戶與 Web 應用…

C# CancellationTokenSource CancellationToken Task.Run傳入token 取消令牌

基本使用方法創建 CancellationTokenSource獲取 CancellationToken將 CancellationToken 傳遞給任務***注意*** 在任務中檢查取消狀態請求取消處理取消異常 高級用法設置超時自動取消或者使用 CancelAfter 方法關聯多個取消令牌注冊回調 注意事項 CancellationTokenSource 是 …

Git 之配置ssh

1、打開 Git Bash 終端 2、設置用戶名 git config --global user.name tom3、生成公鑰 ssh-keygen -t rsa4、查看公鑰 cat ~/.ssh/id_rsa.pub5、將查看到的公鑰添加到不同Git平臺 6、驗證ssh遠程連接git倉庫 ssh -T gitgitee.com ssh -T gitcodeup.aliyun.com

cli命令編寫

新建文件夾 template-cli template-cli下運行 npm init生成package.json 新建bin文件夾和index.js文件 編寫index.js #! /usr/bin/env node console.log(hello cli)package.json增加 bin 字段注冊命令template-cli template-cli命令對應執行的內容文件 bin/index.js 運行 n…

vue3自定義動態錨點列表,實現本頁面錨點跳轉效果

需求&#xff1a;當前頁面存在多個模塊且內容很長時&#xff0c;需要提供一個錨點列表&#xff0c;可以快速查看對應模塊內容 實現步驟&#xff1a; 1.每個模塊添加唯一id&#xff0c;添加錨點列表div <template><!-- 模塊A --><div id"modalA">…

L2TP實驗

一、實驗拓撲 二、實驗內容 手工部署IPec VPN 三、實驗步驟 1、配置接口IP和安全區域 [PPPoE Client]firewall zone trust [PPPoE Client-zone-trust]add int g 1/0/0[NAS]firewall zone untrust [NAS-zone-untrust]add int g 1/0/1 [NAS]firewall zone trust [NAS-zon…

青少年編程與數學 02-012 SQLite 數據庫簡介 01課題、數據庫概要

青少年編程與數學 02-012 SQLite 數據庫簡介 01課題、數據庫概要&#xff09; 一、特點二、功能 課題摘要:SQLite 是一種輕量級的嵌入式關系型數據庫管理系統。 一、特點 輕量級 它不需要單獨的服務器進程來運行。不像 MySQL 或 PostgreSQL 這樣的數據庫系統需要一個專門的服務…

分布式系統面試總結:3、分布式鎖(和本地鎖的區別、特點、常見實現方案)

僅供自學回顧使用&#xff0c;請支持javaGuide原版書籍。 本篇文章涉及到的分布式鎖&#xff0c;在本人其他文章中也有涉及。 《JUC&#xff1a;三、兩階段終止模式、死鎖的jconsole檢測、樂觀鎖&#xff08;版本號機制CAS實現&#xff09;悲觀鎖》&#xff1a;https://blog.…

Ubuntu 系統上完全卸載 Docker

以下是在 Ubuntu 系統上完全卸載 Docker 的分步指南 一.卸載驗證 二.卸載步驟 1.停止 Docker 服務 sudo systemctl stop docker.socket sudo systemctl stop docker.service2.卸載 Docker 軟件包 # 移除 Docker 核心組件 sudo apt-get purge -y \docker-ce \docker-ce-cli …

Postman 版本信息速查:快速定位版本號

保持 Postman 更新至最新版本是非常重要的&#xff0c;因為這能讓我們享受到最新的功能&#xff0c;同時也保證了軟件的安全性。所以&#xff0c;如何快速查看你的 Postman 版本信息呢&#xff1f; 如何查看 Postman 的版本信息教程

EF Core 異步方法

文章目錄 前言一、為什么使用異步方法二、核心異步方法1&#xff09;查詢數據2&#xff09;保存數據3&#xff09;事務處理 三、異步查詢最佳實踐1&#xff09;始終使用 await2&#xff09;組合異步操作3&#xff09;并行查詢&#xff08;謹慎使用&#xff09; 四、異常處理五、…

裝飾器模式介紹和典型實現

裝飾器模式&#xff08;Decorator Pattern&#xff09;是一種結構型設計模式&#xff0c;它允許你通過將對象放入包含行為的特殊封裝對象中來為原對象添加新的功能。裝飾器模式的主要優點是可以在運行時動態地添加功能&#xff0c;而不需要修改原對象的代碼。這使得代碼更加靈活…

【 <二> 丹方改良:Spring 時代的 JavaWeb】之 Spring Boot 中的日志管理:Logback 的集成

<前文回顧> 點擊此處查看 合集 https://blog.csdn.net/foyodesigner/category_12907601.html?fromshareblogcolumn&sharetypeblogcolumn&sharerId12907601&sharereferPC&sharesourceFoyoDesigner&sharefromfrom_link <今日更新> 一、開篇整…

神經網絡知識點整理

目錄 ?一、深度學習基礎與流程 二、神經網絡基礎組件 三、卷積神經網絡&#xff08;CNN&#xff09;?編輯 四、循環神經網絡&#xff08;RNN&#xff09;與LSTM 五、優化技巧與調參 六、應用場景與前沿?編輯 七、總結與展望?編輯 一、深度學習基礎與流程 機器學習流…

【sql優化】where 1=1

文章目錄 where 11問題描述錯誤實現正確實現性能對比測試 where 11 問題描述 在動態 SQL 拼接場景中&#xff0c;開發者常使用 WHERE 11 簡化條件拼接邏輯&#xff08;避免處理首個條件的 AND&#xff09;。理論上&#xff0c;數據庫優化器會忽略 11&#xff0c;但字符串拼接…