系列前言
本系列文章为阅读学习《大数据SQL优化原理与实践》陈鹤 杨国栋◎著 一书的学习笔记。在阅读整篇之后,进行提炼和个人思考,欢迎讨论。
此书共分为4篇,包括10章。
认知篇(第1章)主要面向初学者阐述为什么大数据计算或存储引擎发展至今,最终都会选择以SQL作为统一查询语言的原因及利弊,大数据SQL从业者目前面临的主要问题是什么,以及调优的两个根本目标。
原理篇(第2章)以深入浅出的方式解读SQL的本质,为了降低读者理解的门槛,本篇还以Hive、Spark和Flink这三个主流的引擎框架为例,从源码的角度探索SQL执行背后的秘密。
实践篇(第3-9章)首先深入解读引擎查询优化器的两大优化策略------基于规则的优化和基于代价的优化的实现原理、示例和局限性,然后以Hive、Saprk、Flink等主流引擎为蓝本,探索SQL优化(包括结构与参数调优、子查询优化、连接优化、聚合优化)的解决思路和方法论,并给出作者的多年总结的一些"坑"。
案例篇(第10章)以实践篇的各种真实需求调优历程为基础,以点带面,以小明大,分享电商、金融、银行这三个典型行业的典型公司大数据SQL调优案例,还给出了内容平台数仓、查询高可用、实时性数仓等业务场景的解决方案。
SQL执行过程
数据处理技术的本质就是存储和计算,面对数据的爆发式增长,传统数据库的数据处理能力显得难以为继,也对数据处理技术(即大数据处理技术)带来了新的场景和挑战。在上一篇中,提到了声明式编程语言SQL作为数据库的通用查询语言,其因为广泛支持的数据查询功能、丰富的内置函数以及ANSI标准化的语言结构便于用户学习和使用。那么SQL语言在数据库和计算引擎中分别是如何运行的呢?面对数据量爆发式增长的同时,用户对于数据处理能力提出了更高的要求,他们又是怎么实现和技术演进的?
数据库 Oracle SQL执行过程
-
语句检查(Syntax Check) :Oracle会对提交的SQL语句进行语法检查、语义检查、权限验证,包括SQL语句的拼写是否正确以及是否具备表读写权限等。
-
共享池检查(Shared Pool Check) :Oeacle会维护一个SGA(System Global Area,主要由共享池、数据缓冲区、日志缓冲区构成)的共享池内的库缓存(Library Cache,用来存放可执行的SQL的共享内存结构),在其中搜索匹配共享游标,匹配成功会重用该游标中的解析树和执行计划,省略"查询转换"和"查询优化"步骤,直接进入执行阶段。
- 软解析(Soft Parse) :对于那些已经在共享池中存在的语句,可能会经历"软解析"(Soft Parse),这是一个更快速的过程,只需要验证语句的有效性而不需要重新生成执行计划。
- 硬解析(Hard Parse) :对于首次执行的新语句,会经历"硬解析"(Hard Parse),即从头开始构建执行计划,并对其进行优化。
-
语句执行(Execution) :获取到执行计划后,Oracle会按照执行计划进行SQL语句执行,并将结果返回给用户。
大数据计算引擎 Spark SQL执行过程
- 语法解析(Parsing) :Spark SQL首先会将SQL语句转换成抽象语法树(AST),这是一个表示SQL语句结构的内部数据结构。此阶段确保SQL语句符合SQL语法规范。
- 语义分析(Semantic Analysis) :在语义分析阶段,Spark SQL验证SQL语句逻辑上的正确性。这包括检查表和列是否存在、类型是否兼容等。此外,它还会解析视图和其他对象,并绑定标识符到实际的数据源或字段。
- 逻辑计划生成(Logical Plan Generation) :基于解析后的抽象语法树,Spark SQL构建一个逻辑查询计划。这个计划是查询的一个高层次表示,不依赖任何特定的物理实现细节。它描述了查询的操作,例如选择、投影、过滤、连接等。
- 基于规则的优化(RBO) :在这一阶段,Spark应用一系列预定义的规则来优化逻辑计划。这些规则包括不限于查询重写、谓词下推、视图合并等。RBO的目标是通过应用已知的最佳实践来改进查询计划,而不需要对数据分布有深入了解。
- 基于成本的优化(CBO) :如果启用了CBO并且有足够的统计信息可用,Spark SQL会尝试计算不同执行计划的成本,并选择最有效的那个。CBO考虑了多种因素,如行数估计、数据分布、索引使用情况等,以决定最佳的执行路径。为了支持CBO,用户需要确保数据库中有准确的统计信息,可以通过
ANALYZE
命令来收集。 - 物理计划生成(Physical Plan Generation) :经过逻辑计划优化后,Spark SQL会生成具体的物理执行计划。这涉及到为每个操作选择适当的算法(例如,哈希连接还是排序-合并连接),以及确定如何在集群中分布式地执行这些操作。
- 语句执行(Execution) :最终,物理计划被提交给执行引擎。在执行期间,Spark SQL负责协调任务调度、数据分片、并行化执行等工作。结果集将根据查询类型(如SELECT查询)返回给用户或应用程序。
MPP数据库 Doris SQL执行过程
- 语法解析(Parsing) :SQL查询语句被转换成抽象语法树(AST),这是对SQL语句结构的一种内部表示。解析器负责检查SQL语句的语法正确性,并将SQL文本转换为计算机可以理解的数据结构。
- 语义分析(Semantic Analysis) :确保SQL查询逻辑上是正确的。这包括验证表名、列名是否存在,检查类型兼容性,解析并绑定标识符到它们所代表的对象(如表、列等),以及执行其他必要的检查来确保查询的有效性。
- 单机执行计划生成(Single Plan) :基于之前得到的AST和分析结果,创建一个初步的执行计划。此计划考虑了单台机器上的资源利用,比如如何最有效地使用CPU、内存等资源来执行查询操作。它可能包含查询重写、优化规则的应用,以提高效率。
- 分布式执行计划生成(Distributed Plan) "基于单机执行计划,下一步就是将其扩展到分布式环境中。这一步骤涉及到决定哪些部分可以在集群的不同节点上并行执行,数据如何在节点之间传输,以及如何合并各个节点的结果。目的是最大化并发性和最小化网络通信成本。
- 语句执行(Execution) :系统根据生成的分布式执行计划,安排任务到集群中的各个工作节点上去执行。这通常涉及到负载均衡、故障恢复机制、任务优先级设定等策略,以确保整个查询能够高效且可靠地完成。
SQL抽象语法树
抽象语法树是一种表示编程语言源代码结构的数据结构,通常以树的形式组织。AST中的每个节点代表源代码中的一个构造元素,如表达式、语句或声明。这种表示方式简化了编译器或解释器对源代码的分析和处理,因为它去除了无关紧要的细节(例如括号和分隔符),并且清晰地展示了程序的层次结构。
SQL抽象语法树是特定于SQL语言的抽象语法树,用于表示SQL查询语句的结构。在SQL解析过程中,原始的SQL文本被转换成一个SQL AST,主要包括:
- 词法分析 :SQL查询首先被分解为一系列的标记(tokens),这些标记是构成SQL语句的基本单元,比如关键字(如
SELECT
,FROM
)、标识符(表名、列名)、操作符(如=
,<
,>
)、字面量(字符串、数字)等。 - 语法解析 :通过使用预定义的SQL语法规则,解析器将标记序列转换为一棵树形结构------SQL AST。这棵树的根节点通常是整个查询语句,而子节点则对应着查询的不同组成部分,如
SELECT
列表、FROM
子句、WHERE
条件等。
以该SQL为例:
sql
SELECT id,name FROM user WHERE status = 'ACTIVE' AND age > '20';
其SQL抽象语法树为:
小结
SQL执行过程涉及多个阶段,从语法解析到最终执行。传统数据库如Oracle和大数据计算引擎如Spark SQL以及MPP数据库如Doris在处理SQL查询时都遵循解析、分析、优化和执行的基本流程。
Oracle SQL执行过程首先对SQL语句进行语法检查、语义检查和权限验证,确保其正确性和合法性。接着,通过共享池检查以决定是否可以重用已有的解析树和执行计划(软解析),若不能则需进行硬解析生成新的执行计划。最后,按照确定的执行计划执行SQL语句并返回结果。
Spark SQL则将SQL语句转换为抽象语法树(AST),然后进行语义分析,构建逻辑计划,并通过基于规则(RBO)和基于成本(CBO)的优化策略改进逻辑计划。随后生成物理执行计划,该计划被提交给执行引擎以分布式方式执行,最大化利用集群资源。
Doris同样从解析SQL开始,经过语义分析后,先生成单机执行计划,再扩展至分布式执行计划,最终调度到各个节点上执行,保证高效并发与最小化网络开销。
所有这些系统都会创建一个SQL抽象语法树(AST) ,它是一种内部表示形式,用于简化SQL语句的结构化表示。AST去除无关细节,保留了查询的核心构造,使得后续的分析、优化和执行更加简便。例如,对于SELECT id, name FROM user WHERE status = 'ACTIVE' AND age > 20;
这样的SQL语句,AST会清晰地展示选择项、表名、条件等元素之间的关系,为编译器或解释器提供易于处理的数据结构,从而支持高效的查询处理。
尽管每个系统的具体机制有所不同,但它们都致力于通过高效的SQL执行来满足日益增长的数据处理需求,同时保持良好的性能和可靠性。随着数据量的增长和应用场景的不断变化,这些系统需要技术不断演进,引入更多优化措施以应对挑战,如向量化存储和计算、行列混存、读写分离、湖仓一体等。
微信号:Lzc543621
公众号:阿丞的数据漫谈
社区:PowerData
关于作者
曾从事于世界500强企业,多年能源电力及企业数字化转型项目经验,深度参与和设计多个国网新型电力系统及数字化转型项目。
公众号聚焦数据及人工智能领域,不定期分享能源电力行业知识、数据科学、学习笔记等。尽可能All in原创,All in 干货。
关于社区
PowerData社区是由一群数据从业人员,因为热爱凝聚在一起,以开源精神为基础,组成的数据开源社区。
社区群内会定期组织模拟面试、线上分享、行业研讨(涉及金融、医疗、能源、工业、互联网等)、线下Meet UP、城市聚会、求职内推等。同时,在社区群内您可以进行技术讨论、问题请教,解释更多志同道合的数据朋友。
社区整理了一份每日一题汇总及社区分享PPT,内容涵盖大数据组件、编程语言、数据结构与算法、企业真实面试题等各个领域,帮助您自我提升,成功上岸。可以添加作者微信(Lzc543621),进入PowerData官方社区群。