一、什么是SQL

sql(Structured Query Language: 结构化查询语言)是高级的费过程化编程语言,允许用户在高层数据结构上工作, 是一种数据查询和程序设计语言, 也是(ANSI)的一项标准的计算机语言. but... 目前仍然存在着许多不同版本的sql语言,为了与ANSI标准相兼容, 它们必须以相似的方式共同地来支持一些主要的命令(比如SELECT、UPDATE、DELETE、INSERT、WHERE等等).

在标准SQL中, SQL语句包含四种类型

DML(Data Manipulation Language):数据操作语言,用来定义数据库记录(数据)。

DCL(Data Control Language):数据控制语言,用来定义访问权限和安全级别。

DQL(Data Query Language):数据查询语言,用来查询记录(数据)。

DDL(Data Definition Language):数据定义语言,用来定义数据库对象(库,表,列等)

二、如何执行SQL

2.1 mysql

以mysql为例, sql执行流程大致分为以下节点(mysql server层代码, 不包含引擎层事务/log等操作):

mysqlLex: mysql自身的词法分析程序, C++语言开发, 基于输入的语句进行分词, 并解析除每个分词的意义. 分词的本质便是正则表达式的匹配过程. 源码在sql/sql_lex.cc

Bision: 根据mysql定义的语法规则,进行语法解析,语法解析就是生成语法树的过程. 核心是如何涉及合适的存储结构以及相关算法,去存储和遍历所有的信息

语法解析中,生成语法树:

mysql分析器: SQL解析, 针对关键词/非关键词进行提取、解析, 并生成解析语法树. 如果分析到语法错误,会抛出异常: ERROR: You have an error in your SQL syntax. 同时该阶段也会做一些校验, 如不存在字段会抛出异常: unknow column in field list.

引申点:

a. 语法树生成规则

b. mysql的优化规则

2.2 hive sql

Hive 是基于Hadoop 构建的一套数据仓库分析系统,它提供了丰富的SQL查询方式来分析存储在Hadoop 分布式文件系统中的数据,可以将结构化的数据文件映射为一张数据库表,并提供完整的SQL查询功能,可以将SQL语句转换为MapReduce任务进行运行,通过自己的SQL 去查询分析需要的内容,这套SQL 简称Hive SQL,使不熟悉mapreduce 的用户很方便的利用SQL 语言查询,汇总,分析数据

hive架构图:

Driver:

输入了sql字符串,对sql字符串进行解析,转化程抽象语法树,再转化成逻辑计划,然后使用优化工具对逻辑计划进行优化,最终生成物理计划(序列化反序列化,UDF函数),交给Execution执行引擎,提交到MapReduce上执行(输入和输出可以是本地的也可以是HDFS/Hbase)见下图的hive架构

hiveSql的执行流程如下:

sql写出来以后只是一些字符串的拼接,所以要经过一系列的解析处理,才能最终变成集群上的执行的作业

(1)Parser:将sql解析为AST(抽象语法树),会进行语法校验,AST本质还是字符串

(2)Analyzer:语法解析,生成QB(query block)

(3)Logicl Plan:逻辑执行计划解析,生成一堆Opertator Tree

(4)Logical optimizer:进行逻辑执行计划优化,生成一堆优化后的Opertator Tree

(5)Phsical plan:物理执行计划解析,生成tasktree

(6)Phsical Optimizer:进行物理执行计划优化,生成优化后的tasktree,该任务即是集群上的执行的作业

结论:经过以上的六步,普通的字符串sql被解析映射成了集群上的执行任务,最重要的两步是 逻辑执行计划优化和物理执行计划优化(图中红线圈画)

Antlr: Antrl是一种语言识别的工具, 基于java开发, 可以用来构造领域语言. 它提供了一个框架,可以通过包含java, C++, 或C#动作(action)的语法描述来构造语言识别器, 编译器和解释器.Antlr完成了hive 词法分析、语法分析、语义分析、中间代码生成的过程.

AST语法树举例:

引申学习:

a. 从hivesql的执行机制可以看出, hive并不适合用于联机事务处理, 无法提供实时查询功能;最适合应用在基于大量不可变数据的批处理作业

b. Antlr的解析流程

c. hive的优化规则

2.3 flink sql

Flink SQL是Flink中最高级的抽象, 可以划分为 SQL --> Table API --> DataStream/DataSetAPI --> Stateful Stream Processing

Flink SQL包含 DML 数据操作语言、 DDL 数据语言, DQL 数据查询语言,不包含DCL语言。

(1)首先,FlinkSQL 底层使用的是 apache Calcite 引擎来处理SQL语句,Calcite会使用 javaCC 做SQL解析,javaCC根据Calcite中定义的 Parser.jj 文件,生成一系列的java代码,生成的java代码会把SQL转换成AST抽象语法树(即SQLNode类型)。

(2)生成的 SqlNode 抽象语法树,他是一个未经验证的抽象语法树,这时 SQL Validator 会获取 Flink Catalog 中的元数据信息来验证 sql 语法,元数据信息检查包括表名,字段名,函数名,数据类型等检查。然后生成一个校验后的SqlNode。

(3)到达这步后,只是将 SQL 解析到 java 数据结构的固定节点上,并没有给出相关节点之间的关联关系以及每个节点的类型信息。

所以,还需要将 SqlNode 转换为逻辑计划,也就是LogicalPlan,在转换过程中,会使用 SqlToOperationConverter 类,来将 SqlNode 转换为 Operation,Operation 会根据SQL语法来执行创建表或者删除表等操作,同时FlinkPlannerImpl.rel()方法会将SQLNode转换成RelNode树,并返回RelRoot。

(4)第4步将执行 Optimize 操作,按照预定义的优化规则 RelOptRule 优化逻辑计划。

Calcite 中的优化器RelOptPlanner有两种,一是基于规则优化(RBO)的HepPlanner,二是基于代价优化(CBO)的VolcanoPlanner。然后得到优化后的RelNode, 再基于Flink里面的rules将优化后的逻辑计划转换成物理计划。

(5)第5步 执行 execute 操作,会通过代码生成 transformation,然后递归遍历各节点,将DataStreamRelNode 转换成DataStream,在这期间,会依次递归调用DataStreamUnion、DataStreamCalc、DataStreamScan类中重写的 translateToPlan方法。递归调用各节点的translateToPlan,实际是利用CodeGen元编成Flink的各种算子,相当于直接利用Flink的DataSet或者DataStream开发程序。

(6)最后进一步编译成可执行的 JobGraph 提交运行。

Flink SQL使用 Apache Calcite 作为解析器和优化器

Calcite : 一种动态数据管理框架,它具备很多典型数据库管理系统的功能 如SQL 解析、 SQL 校验、 SQL 查询优化、 SQL 生成以及数据连接查询等,但是又省略了一些关键的功能,如 Calcite并不存储相关的元数据和基本数据,不完全包含相关处理数据的算法等。

引申学习:

a. flink sql优化规则

三、常见SQL解析引擎

解析引擎 开发语言 使用场景 总结
antlr java presto 1. 包含三大主要功能: 词法分析器、语法分析器、树解析器2. 支持定义领域语言
calcite javaCC flink 1. 抽象语法树2. 支持使用 FreeMarker 模版引擎扩展语法3. 能够与数据库创建查询

持续补充ing...

四、总结

在实际工作过程中会涉及到相关的sql优化, 比如将非研发的业务老师写的复杂嵌套sql后台自动改为非嵌套执行,提高查询性能. 支持redisSQL, 以标准SQL格式解析成后台可执行的redis命令. 目前采用的开源jsqlparser框架来实现语法树的解析, 好处是操作简单, 只对sql语句进行拆分, 解析成java类的层次结构,支持visitor模式, 与数据库无关. 缺点是只支持常见的SQL语法集, 如若要扩展语法需改其源码, 对代码的侵入性与维护性造成影响.想要做好sql解析优化相关的工作, 还是要深入了解sql的执行原理, 了解各个sql引擎的特点与优劣. 站在架构的角度来思考来思考问题.

工欲善其事,必先利其器.

作者:京东科技 李丹枫

来源:京东云开发者社区 转载请注明来源

老知识复盘-SQL从提交到执行到底经历了什么的更多相关文章

  1. c#Winform程序调用app.config文件配置数据库连接字符串 SQL Server文章目录 浅谈SQL Server中统计对于查询的影响 有关索引的DMV SQL Server中的执行引擎入门 【译】表变量和临时表的比较 对于表列数据类型选择的一点思考 SQL Server复制入门(一)----复制简介 操作系统中的进程与线程

    c#Winform程序调用app.config文件配置数据库连接字符串 你新建winform项目的时候,会有一个app.config的配置文件,写在里面的<connectionStrings n ...

  2. Apache Spark源码走读之11 -- sql的解析与执行

    欢迎转载,转载请注明出处,徽沪一郎. 概要 在即将发布的spark 1.0中有一个新增的功能,即对sql的支持,也就是说可以用sql来对数据进行查询,这对于DBA来说无疑是一大福音,因为以前的知识继续 ...

  3. 【SQL进阶】03.执行计划之旅1 - 初探

    听到大牛们说执行计划,总是很惶恐,是对知识的缺乏的惶恐,所以必须得学习执行计划,以减少对这一块知识的惶恐,下面是对执行计划的第一讲-理解执行计划. 本系列[T-SQL]主要是针对T-SQL的总结. S ...

  4. MySQL 笔记整理(2) --日志系统,一条SQL查询语句如何执行

    笔记记录自林晓斌(丁奇)老师的<MySQL实战45讲> 2) --日志系统,一条SQL查询语句如何执行 MySQL可以恢复到半个月内任意一秒的状态,它的实现和日志系统有关.上一篇中记录了一 ...

  5. Spark源码剖析 - 任务提交与执行

    1. 任务概述 任务提交与执行过程: 1) build operator DAG:此阶段主要完成RDD的转换及DAG的构建: 2) split graph into stages of tasks:此 ...

  6. (原)SQL Server 代理作业执行持续时间简述

    本文目录列表: 1.SQL Server 代理作业概述2.获取代理作业执行时间方法一 3.获取代理作业执行时间方法二4.总结语 5.参考目录清单列表 正文:   1.SQL Server 代理作业概述 ...

  7. 同一SQL语句在PLSQL Developer与SQL * PLUS工具中执行结果不一致

    背景 今天遇到如下问题,同一sql语句在PLSQL Developer与SQL*PLUS工具中执行结果不一致, sql语句如下 SELECT 'GROUPHEALTH_SEND_EMAIL' as i ...

  8. SQL更新语句的执行

    联系上文SQL查询语句的执行 查询语句的那一套流程,更新语句也是同样会走一遍. 更新流程还涉及两个重要的日志模块: ​ redo log(重做日志)和 binlog(归档日志) redo log:重做 ...

  9. [源码分析] 带你梳理 Flink SQL / Table API内部执行流程

    [源码分析] 带你梳理 Flink SQL / Table API内部执行流程 目录 [源码分析] 带你梳理 Flink SQL / Table API内部执行流程 0x00 摘要 0x01 Apac ...

  10. 阿里一面,给了几条SQL,问需要执行几次树搜索操作?

    前言 有位朋友去阿里面试,他说面试官给了几条查询SQL,问:需要执行几次树搜索操作?我朋友当时是有点懵的,后来冷静思考,才发现就是考索引的几个基础知识点~~ 本文我们分九个索引知识点,一起来探讨一下. ...

随机推荐

  1. ubuntu下安装mysqlclient报错

    输入以下代码: 1 解决方法: 2 sudo apt-get install libmysqlclient-dev 3 4 再次安装: 5 pip3 install mysqlclient 文章链接: ...

  2. Python类与面向对象

    Python类与面向对象 一.面向对象 1.1 面向对象概述 面向对象与面向过程? 面向过程编程的基本思想是:分析解决问题的步骤,使用函数实现每步对应的功能,按照步骤的先后顺序依次调用函数.面向过程只 ...

  3. 2023-08-02:给定一棵树,一共有n个点, 每个点上没有值,请把1~n这些数字,不重复的分配到二叉树上, 做到 : 奇数层节点的值总和 与 偶数层节点的值总和 相差不超过1。 返回奇数层节点分配

    2023-08-02:给定一棵树,一共有n个点, 每个点上没有值,请把1~n这些数字,不重复的分配到二叉树上, 做到 : 奇数层节点的值总和 与 偶数层节点的值总和 相差不超过1. 返回奇数层节点分配 ...

  4. [Go笔记] 基础-01: Golang发展简史、著名项目及基本使用

    引言 Golang,又称Go语言,是一门开源的静态类型编译型编程语言.自从2007年由谷歌的罗伯特·格里泽默(Robert Griesemer).罗布·派克(Rob Pike)和肯·汤普森(Ken T ...

  5. [python]爬取手机号码前缀和地区信息

    概述 使用python爬取手机号码前缀7位.区号和地区. 小网站不容易,对爬虫也挺友好,就不放链接了. 代码 import requests from lxml import etree from f ...

  6. Go的任务调度单元与并发编程

    摘要:本文由葡萄城技术团队于博客园原创并首发.转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 前言 本文主要介绍Go语言.进程.线程.协程的出现背景原因以及 ...

  7. 论文解读(MetaAdapt)《MetaAdapt: Domain Adaptive Few-Shot Misinformation Detection via Meta Learning》

    Note:[ wechat:Y466551 | 可加勿骚扰,付费咨询 ] 论文信息 论文标题:MetaAdapt: Domain Adaptive Few-Shot Misinformation De ...

  8. springboot下载文件 范围下载

    springboot下载文件 范围下载 关键词:springboot,download,Range,Content-Range,Content-Length,http code 206 Partial ...

  9. SpringBoot整合ueditor编辑器

    1.到ueditor编辑器官网下载jsp版(目前官网地址改为了GitHub)https://ueditor.baidu.com/website/download.html2.下载解压后复制到当前项目3 ...

  10. 循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(1)

    在我们的SqlSugar的开发框架中,整合了Winform端.Vue3+ElementPlus的前端.以及基于UniApp+Vue+ThorUI的移动前端几个前端处理,基本上覆盖了我们日常的应用模式了 ...