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.mzph.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;但字符串拼接…