Doris数据库FE——SQL handleQuery

news2024/11/19 7:48:33

SQL解析在下文中指的是将一条sql语句经过一系列的解析最后生成一个完整的物理执行计划的过程。这个过程包括以下四个步骤:词法分析、语法分析、生成逻辑计划、生成物理计划。Doris SQL解析具体包括了六个步骤:词法分析,语法分析、语义分析,生成单机逻辑计划,生成分布式逻辑计划,生成物理计划。具体代码实现上包含以下五个步骤:Parse、Analyze、SinglePlan、DistributedPlan、Schedule。
在这里插入图片描述

Parse

Parser阶段主要包含对新一代优化器NeridsParser解析器的调用(在COM_QUERY且Nereid优化器开启的情况下)NereidsParser().parseSQL(originStmt),其生成的Statement是LogicalPlanAdapter类类型;如果关闭Nereid优化器或fall behind,就会触发legacy优化器,也就是调用parse函数,原始解析流程。
在这里插入图片描述

Analyze、SinglePlan、DistributedPlan、Schedule

StmtExecutor类包含了Analyze、SinglePlan、DistributedPlan、Schedule功能。
在这里插入图片描述
Analyze主要是对Parse阶段生成的抽象语法树AST进行一些前期的处理和语义分析,为生成单机逻辑计划做准备。抽象语法树是由StatementBase这个抽象类表示。这个抽象类包含一个最重要的成员函数analyze(),用来执行Analyze阶段要做的事。不同类型的查询select, insert, show, set, alter table, create table等经过Parse阶段后生成不同的数据结构(SelectStmt, InsertStmt, ShowStmt, SetStmt, AlterStmt, AlterTableStmt, CreateTableStmt等),这些数据结构继承自StatementBase,并实现analyze()函数,对特定类型的SQL进行特定的Analyze。例如:select类型的查询,会转成对select sql的子语句SelectList, FromClause, GroupByClause, HavingClause, WhereClause, SortInfo等的analyze()。然后这些子语句再各自对自己的子结构进行进一步的analyze(),通过层层迭代,把各种类型的sql的各种情景都分析完毕。例如:WhereClause进一步分析其包含的BetweenPredicate(between表达式), BinaryPredicate(二元表达式), CompoundPredicate(and or组合表达式), InPredicate(in表达式)等。
对于查询类型的SQL,包含以下几项重要工作:
· 元信息的识别和解析:识别和解析sql中涉及的 Cluster, Database, Table, Column 等元信息,确定需要对哪个集群的哪个数据库的哪些表的哪些列进行计算。
· SQL 的合法性检查:窗口函数不能 DISTINCT,投影列是否有歧义,where语句中不能含有grouping操作等。
· SQL 简单重写:比如将 select * 扩展成 select 所有列,count distinct转成bitmap或者hll函数等。
· 函数处理:检查sql中包含的函数和系统定义的函数是否一致,包括参数类型,参数个数等。
· Table 和 Column 的别名处理
· 类型检查和转换:例如二元表达式两边的类型不一致时,需要对其中一个类型进行转换(BIGINT 和 DECIMAL 比较,BIGINT 类型需要 Cast 成 DECIMAL)。
对AST 进行analyze后,会再进行一次rewrite操作,进行精简或者是转成统一的处理方式。目前rewrite的算法是基于规则的方式,针对AST的树状结构,自底向上,应用每一条规则进行重写。如果重写后,AST有变化,则再次进行analyze和rewrite,直到AST无变化为止。例如:常量表达式的化简:1 + 1 + 1 重写成 3,1 > 2 重写成 Flase 等。将一些语句转成统一的处理方式,比如将 where in, where exists 重写成 semi join, where not in, where not exists 重写成 anti join。

生成单机逻辑Plan阶段,这部分工作主要是根据AST抽象语法树生成代数关系,也就是俗称的算子数。树上的每个节点都是一个算子,代表着一种操作。具体来说这个阶段主要做了如下几项工作:
· Slot 物化:指确定一个表达式对应的列需要 Scan 和计算,比如聚合节点的聚合函数表达式和 Group By 表达式需要进行物化。
· 投影下推:BE 在 Scan 时只会 Scan 必须读取的列。
· 谓词下推:在满足语义正确的前提下将过滤条件尽可能下推到 Scan 节点。
· 分区,分桶裁剪:根据过滤条件中的信息,确定需要扫描哪些分区,哪些桶的tablet。
· Join Reorder:对于 Inner Join, Doris 会根据行数调整表的顺序,将大表放在前面。
· Sort + Limit 优化成 TopN:对于order by limit语句会转换成TopN的操作节点,方便统一处理。
· MaterializedView 选择:会根据查询需要的列,过滤,排序和 Join 的列,行数,列数等因素选择最佳的物化视图。

生成分布式Plan阶段,有了单机的PlanNode树之后,就需要进一步根据分布式环境,拆成分布式PlanFragment树(PlanFragment用来表示独立的执行单元),毕竟一个表的数据分散地存储在多台主机上,完全可以让一些计算并行起来。这个步骤的主要目标是最大化并行度和数据本地化。主要方法是将能够并行执行的节点拆分出去单独建立一个PlanFragment,用ExchangeNode代替被拆分出去的节点,用来接收数据。拆分出去的节点增加一个DataSinkNode,用来将计算之后的数据传送到ExchangeNode中,做进一步的处理。这一步采用递归的方法,自底向上,遍历整个PlanNode树,然后给树上的每个叶子节点创建一个PlanFragment,如果碰到父节点,则考虑将其中能够并行执行的子节点拆分出去,父节点和保留下来的子节点组成一个parent PlanFragment。拆分出去的子节点增加一个父节点DataSinkNode组成一个child PlanFragment,child PlanFragment指向parent PlanFragment。这样就确定了数据的流动方向。对于查询操作来说,join操作是最常见的一种操作。
Doris目前支持4种join算法:broadcast join,hash partition join,colocate join,bucket shuffle join。
· broadcast join:将小表发送到大表所在的每台机器,然后进行hash join操作。当一个表扫描出的数据量较少时,计算broadcast join的cost,通过计算比较hash partition的cost,来选择cost最小的方式。
· hash partition join:当两张表扫描出的数据都很大时,一般采用hash partition join。它遍历表中的所有数据,计算key的哈希值,然后对集群数取模,选到哪台机器,就将数据发送到这台机器进行hash join操作。
· colocate join:两个表在创建的时候就指定了数据分布保持一致,那么当两个表的join key与分桶的key一致时,就会采用colocate join算法。由于两个表的数据分布是一样的,那么hash join操作就相当于在本地,不涉及到数据的传输,极大提高查询性能。
· bucket shuffle join:当join key是分桶key,并且只涉及到一个分区时,就会优先采用bucket shuffle join算法。由于分桶本身就代表了数据的一种切分方式,所以可以利用这一特点,只需将右表对左表的分桶数hash取模,这样只需网络传输一份右表数据,极大减少了数据的网络传输,如图10所示。

Schedule阶段,这一步是根据分布式逻辑计划,创建分布式物理计划。主要解决以下问题:哪个 BE 执行哪个 PlanFragment?每个 Tablet 选择哪个副本去查询?如何进行多实例并发?
创建分布式物理计划的核心流程:
a. prepare阶段:给每个PlanFragment创建一个FragmentExecParams结构,用来表示PlanFragment执行时所需的所有参数;如果一个PlanFragment包含有DataSinkNode,则找到数据发送的目的PlanFragment,然后指定目的PlanFragment的FragmentExecParams的输入为该PlanFragment的FragmentExecParams。
b. computeScanRangeAssignment阶段:针对不同类型的join进行不同的处理。
· computeScanRangeAssignmentByColocate:针对colocate join进行处理,由于join的两个表桶中的数据分布都是一样的,他们是基于桶的join操作,所以在这里是确定每个桶选择哪个host。在给host分配桶时,尽量保证每个host分配到的桶基本平均。
· computeScanRangeAssignmentByBucket:针对bucket shuffle join进行处理,也只是基于桶的操作,所以在这里是确定每个桶选择哪个host。在给host分配桶时,同样需要尽量保证每个host分配到的桶基本平均。
· computeScanRangeAssignmentByScheduler:针对其他类型的join进行处理。确定每个scanNode读取tablet哪个副本。一个scanNode会读取多个tablet,每个tablet有多个副本。为了使scan操作尽可能分散到多台机器上执行,提高并发性能,减少IO压力,Doris采用了Round-Robin算法,使tablet的扫描尽可能地分散到多台机器上去。例如100个tablet需要扫描,每个tablet 3个副本,一共10台机器,在分配时,保障每台机器扫描10个tablet。
c. computeFragmentExecParams阶段:这个阶段解决PlanFragment下发到哪个BE上执行,以及如何处理实例并发问题。确定了每个tablet的扫描地址之后,就可以以地址为维度,将FragmentExecParams生成多个实例,也就是FragmentExecParams中包含的地址有多个,就生成多个实例FInstanceExecParam。如果设置了并发度,那么一个地址的执行实例再进一步的拆成多个FInstanceExecParam。针对bucket shuffle join和colocate join会有一些特殊处理,但是基本思想一样。FInstanceExecParam创建完成后,会分配一个唯一的ID,方便追踪信息。如果FragmentExecParams中包含有ExchangeNode,需要计算有多少senders,以便知道需要接受多少个发送方的数据。最后FragmentExecParams确定destinations,并把目的地址填充上去。
d. create result receiver阶段:result receiver是查询完成后,最终数据需要输出的地方。
e. to thrift阶段:根据所有PlanFragment的FInstanceExecParam创建rpc请求,然后下发到BE端执行。这样一个完整的SQL解析过程完成了。

在这里插入图片描述

https://blog.csdn.net/weixin_37850264/article/details/112761773

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

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

相关文章

文件系统详解

目录 文件系统(1) 第一节文件系统的基本概念 一、文件系统的任务 二、文件的存储介质及存储方式 三、文件的分类 第二节 文件的逻辑结构和物理结构 一、文件的逻辑结构 二、文件的物理结构 文件系统(2) 第三节 文件目…

Oracle for Windows安装和配置——Oracle for Windows数据库创建及测试

2.2. Oracle for Windows数据库创建及测试 2.2.1. 创建数据库 1)启动数据库创建助手(DBCA) 进入%ORACLE_HOME%\bin\目录并找到“dbca”批处理程序,双击该程序。具体如图2.1.3-1所示。 图2.1.3-1 双击“%ORACLE_HOME%\bin\dbca”…

mac 配置 httpd nginx php-fpm 详细记录 已解决

在日常mac电脑 开发php项目一直是 httpd 方式 运行,由于有 多版本 运行的需求,docker不想用,索性用 php-fpm进行 功能处理。上次配置 是好的,但是感觉马马虎虎,这次 配置底朝天。因为配置服务器,几乎也都是…

9. Java字符串支持正则表达式的方法

Java —— String字符串 1. 正则表达式2. String正则API3. Object类和toString方法4. equals方法5. 包装类及Number 1. 正则表达式 正则表达式(Regular Expression):简称为Regex或RegExp,是一种用于描述字符串模式的工具 作用&…

Jmeter性能测试步骤

Jmeter多用户并发测试 第1步, 在安装目录下的bin文件夹下打开Jmeter,如下图 第2步,新建一个线程组 第3步,新建一个HTTP请求,这里给这个请求重命名为getMsgSum 设置HTTP请求的IP端口,以及路径等 第4步&#…

SoftwareTest3 - 要了人命的Bug

软件测试基础篇 一 . 如何合理的创建一个 Bug二 . Bug 等级2.1 崩溃2.2 严重2.3 一般2.4 次要 三 . Bug 的生命周期四 . 跟开发产生争执应该怎么解决 Hello , 大家好 , 又给大家带来新的专栏喽 ~ 这个专栏是专门为零基础小白从 0 到 1 了解软件测试基础理论设计的 , 虽然还不足…

C++ -- 特殊类设计

目录 设计一个类,不能被拷贝 C98的做法 C11的做法 设计一个类,只能在堆上创建对象 实现方式1 实现方式2 设计一个类,只能在栈上创建对象 实现方式1 方式1的优化 实现方式2 设计一个类,不能被继承 设计模式 什么是设计…

怒刷LeetCode的第9天(Java版)

目录 第一题 题目来源 题目内容 解决方法 方法一:双指针 方法二:递归 方式三:迭代 方法四:优先队列 第二题 题目来源 题目内容 解决方法 方法一:贪心算法 方法二:数学方法 方法三&#xff1…

iOS应用中的内存泄漏问题解决

解决iOS应用中的内存泄漏问题是非常重要的,因为内存泄漏可能导致应用变得缓慢或不稳定。以下是一些解决iOS内存泄漏问题的工具和方法,希望对大家有所帮助。北京木奇移动技术有限公司,专业的软件外包开发公司,欢迎交流合作。 工具&…

HTML5day02综合案例2

案例展示 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>注册信息</title> </head> &l…

MC互联网联机frp实现

我使用的是java版本的MC&#xff0c;联机方式如下。只是一个简单的笔记&#xff0c;所以只说重点。 主机开启局域网 整合包中自带的局域网联网插件&#xff1a;Lan Server Properties 1.10.1 在线模式选择关闭&#xff0c;不然非正版用户无法连接。 frp 具体不说了&#x…

基于MUSIC算法的二维超声波成像matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1、基本原理 4.2、数学公式 4.3、实现过程 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ..........................................…

前端react 18.2整合ckeditor富文本编辑器——配置插件、自定义toolbar工具栏

文章目录 ⭐前言⭐引入ckeditor⭐npm 包引入⭐cdn资源引入 ⭐自定义插件&#x1f496; 自定义yma16配置插件 ⭐总结⭐结束 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;本文分享关于前端react整合ckeditor——配置插件、自定义toolbar工具栏。 react系列往期文章&#xff…

sylixos 5.0.4 ecs

sylixos 5.0.4 ecs 2692407267qq.com&#xff0c;更多内容请见http://user.qzone.qq.com/2692407267/

人类的态势感知可分为先验、似然、后验的三部分

人类的态势感知可以分为先验、似然和后验三个部分。这些部分描述了在不同阶段对环境的感知和理解。先验感知&#xff1a;先验感知基于先前的知识、经验和先验信息来理解环境。它利用已有的知识和模型&#xff0c;进行预测和推断&#xff0c;从而形成对当前环境的初步认知。先验…

Go 并发可视化解释 - sync.Mute

在学习 Go 编程语言时&#xff0c;您可能会遇到这句著名的格言&#xff1a;“不要通过共享内存来进行通信&#xff1b;相反&#xff0c;通过通信来共享内存。” 这句话构成了 Go 强大并发模型的基础&#xff0c;其中通道&#xff08;channels&#xff09;作为协程之间的主要通信…

unity自己对象池的使用

unity出了自己的对象池 这里记录一下用法 命名空间就是这个 一般有两种用法&#xff0c;第一种是在using里面获取&#xff0c;脱离这个域就释放。第二种是在Get和Release配合使用 // This version will only be returned to the pool if we call Release on it.//只有使用Re…

【计算机基础】让我们重新认识一下Visual Stduio及其操作,知识点汇总!!

&#x1f4e2;&#xff1a;如果你也对机器人、人工智能感兴趣&#xff0c;看来我们志同道合✨ &#x1f4e2;&#xff1a;不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】 &#x1f4e2;&#xff1a;文章若有幸对你有帮助&#xff0c;可点赞 &#x1f44d;…

远程连接ubuntu的mysql服务报错10061的解决方案

远程连接ubuntu的mysql服务报错10061的解决方案 我的解决方案是&#xff1a; 首先&#xff1a;进入/etc/mysql/mysql.conf.d文件夹下面&#xff0c;编辑mysqld.cnf文件。如图所示&#xff1a; 然后&#xff1a;将bind-address那一行改成bind-address 0.0.0.0.如图所示&…

李宏毅hw-8,auto-encoder for anomaly_detection

一、查漏补缺、熟能生巧: 主要是mu均值 和 logvar对数标准差 std标准差的 处理方面不熟练 二、代码解读&#xff1a; 1.sample_code中提供了3种model&#xff1a;fcn_model 、 conv_model 和 vae_model: (1)fcn_model的结构非常好理解&#xff1a; 就是通过全连接层进行降维…