CMU 15-721 15-查询执行和处理过程 Query Execution & Processing

本文涉及的产品
云原生数据仓库AnalyticDB MySQL版,基础版 8ACU 100GB 1个月
简介: 数据库架构 从整体数据库架构来看,我们可以知道分为网络协议层、优化器层、执行器、存储,详见下图:SQL从客户端发送到数据库服务端,经过解析器、语法语义分析、逻辑优化和物理优化,从一个字符串转换为解析树、语法树到最终的执行计划,那么最终是如何变成机器可以执行的操作呢,本文重点就是来讲执行器的一些重要组件和原理。

数据库架构

从整体数据库架构来看,我们可以知道分为网络协议层、优化器层、执行器、存储,详见下图:
image
SQL从客户端发送到数据库服务端,经过解析器、语法语义分析、逻辑优化和物理优化,从一个字符串转换为解析树、语法树到最终的执行计划,那么最终是如何变成机器可以执行的操作呢,本文重点就是来讲执行器的一些重要组件和原理。

执行器

我们先来了解下重要的一个查询的执行过程:
一个查询SQL变成执行计划后,既然叫执行计划,那么它一定可以序列化成一系列的操作。执行计划就是由一堆操作符组成的,每个操作符对应的实例对象就是一次操作符作用在一组数据上的调用。一次任务就是一系列这样的一个或多个操作符实例的执行。

执行层的优化

我们现在将要讨论的是那些数据集合能够整个加载到内存中的SQL执行过程中可以进行性能优化的方法。当我们不考虑磁盘问题时候,我们还有其他的一些瓶颈。

优化的目标

1: 减少指令数:用很少的指令去做更多的事情

2: 减少每个指令的周期:在较短周期内执行更多的CPU指令,这意味着需要减少由于cache misses和stalls的缓存加载和存储

3: 并行执行:使用多线程同时并行执行每一条SQL

主要介绍的内容包括:

MonetDB/X100的分析

执行模型

并行执行

MonetDB/X100

MonetDB/X100是从很低角度分析执行瓶颈的一个基于内存的OLAP数据库,它能够证明现在的数据库并没有针对目前CPU的架构体系来进行设计。2010年,被Actian收购后改名叫Vectorwise,后来改称为Actian Vector和Actian Avalanche。

CPU简介

CPUs会把很多指令变为流水线的各个阶段,目的是通过屏蔽那些在一个周期无法完成的指令,从而让所有处理器在一个周期内都能够处于忙碌状态。Super-scalar CPUs可以支持多流水线,即:
→ 如果指令相互独立,在一个周期内可以并行执行多个指令。
→ 费林分类: 单处理指令单数据(SISD)

那么目前数据库中对于CPU设计的问题有哪些呢?

1: 依赖性:如果一个指令依赖于另一个指令,那么它们就不能被立即推到同一个流水线里。

2: 分支预测:CPU尝试着预测程序中某一个代码分支,并将其指令填充到一个流水线里。如果预测失败,那它需要把所有的推测的工作全部扔掉并重新刷新流水线。

分支预测失败

对于长流水线,CPUs通常都会推测执行的代码分支,这里潜在的隐藏了那些互相依赖的执行之间的等待。在数据库领域,在一个顺序扫描中,最多执行的代码分支是filter操作,但是这个几乎不可能预测准确。

选择查询扫描

SELECT * FROM table
WHERE key >= $(low)
AND key <= $(high)

下图可以看到,这条SQL如何通过分支的和无分支的方式进行扫描
image
那么看看效果,无分支较为稳定,而有分支的情况下随着SQL选择率不同表现出不同CPU指令数量的不同
image

过度指令

数据库需要支持不同的数据类型,所以它在对值进行执行任何操作的时候必须去检查值的类型,这样导致了巨大的选择语句,而且CPU都无法预测每一个代码分支。比如Postgres的NUMERIC类型.

执行模型

数据库的执行模型说明了数据库如何执行SQL的执行计划,不同工作的负载有不同的权衡:

1: 迭代模型(Iterator Model)

2: 物化模型(Materialization Model)

3: 向量化/批处理模型(Vectorized / Batch Model)

迭代模型

执行计划中的每个操作符都需要实现next函数,每一次调用,操作符都返回一个tuple或者EOF。实现loop的操作符,可以去调用子操作符的next来获取tuples并行进行处理。这个模型也叫火山模型或者流水线模型。

image

几乎所有的数据库都可以支持tuple的流水化处理,一些操作符可能需要等待它的子操作符返回所有的元组才能继续执行,比如Joins, Subqueries, Order By。这种模型对外输出是非常容易的。

下面是支持这种模型的数据库:
image

物化模型

每一个操作符需要一次性处理很多,然后一次一并对外输出。操作符物化把自己的输出当成一个单独的结果。数据库系统也可以把一些建议下推减少太多的tuples。它可以支持发送一个物化的行或者一个列数据。输出可以是多行(NSM)或者多列(DSM)。

image

这种模型更适合OLTP负载,因为那些查询只一次访问小规模的数据,更小的执行和协调的消耗,更少的函数调用。如果对于那些中间结果集很大的OLAP负载是不适合的。

下面是支持这种模型的数据库:
image

: 向量化和批处理模型

像迭代模型一样,每个操作符都实现了next函数,但是每个指令在内部都一次循环处理多个tuples,每次批处理的大小都取决于迎接或者查询的属性。
image

这种模型是OLAP查询的理想模型,因为它们极大的减少了操作符数量,可以允许操作符使用向量化指令去批量处理tuples,也可以认为是SIMD方式。

下面是支持这种模型的数据库:
image

并行执行

执行计划的处理方式

1: 自顶向下(Top-to-Bottom):开始从顶端从子操作符拉数据,元组通常要通过所有的函数调用。

2: 自底向上(Bottom-to-Top):开始从叶子推送数据到它们的父操作符,允许更严格的控制流水线中的缓存和寄存器。

INTER-QUERY并行

通过允许同时执行多个查询来改进整个的性能,通过并发控制方案去提供一个隔离的错觉,很难提供一个并发的方案不去极大的影响数据库的处理模型。

INTRA-QUERY并行

通过并行执行操作符来改进单查询的性能。

1: Intra-Operator (Horizontal)

2: Inter-Operator (Vertical)

这些技术并不是相互排斥的,每个关系操作符都有相应的并行算法。

Intra-Operator (Horizontal)

操作符并分解成相互独立的实例,用同一函数处理数据的不同子集。数据库用exchange操作符来合并自操作符的结果。

image

Inter-Operator (Vertical)

→ 操作是重叠的,目的是让数据从一个阶段流到下一个阶段,而不进行物化,也叫流水线并行。这种在传统数据库并不常见。不是所有操作符都能够把结果集输出,直到它们能够接收到子操作符的所有tuples,这种方式更多出现在流式处理系统中。

比如下列数据库:
image

这是它们的处理方式:
image

查询计划采用正确数量的workers取决于CPU cores、数据量及对应操作符的功能实现。

Worker的分配方式

1: 每Core一个Worker:每个core可以绑定到一个线程上,参考sched_setaffinity
2: 每Core多个Workers:每个core或者socket可以用在worker池中,允许CPU cores充分被利用。

TASK分配方式

1: Push:一个中心的分配器,分配任务到各个workers,并监控它们的执行过程。当有worker完成任务后,通知分配器分配下一个任务。
1: Pull:workers从队列中取下一个任务并处理,完毕后再处理队列中下一个任务。

最后的思考

最简单的方式是实现对现代CPUs的架构不会总是产生最有效的策略。我们可以看到向量化/自底向上的执行是执行OLAP查询最好的方式。

参考链接和文献:

- 课程原文CMU 15-721 15-查询执行和处理过程 Query Execution & Processing
[- P. Boncz, et al., MonetDB/X100: Hyper-Pipelining Query Execution, in CIDR, 2005
](https://15721.courses.cs.cmu.edu/spring2019/papers/15-execution/boncz-cidr2005.pdf)
- L. Shrinivas, et al., Materialization Strategies in the Vertica Analytic Database: Lessons Learned, in ICDE, 2013 (Optional)

相关实践学习
AnalyticDB MySQL海量数据秒级分析体验
快速上手AnalyticDB MySQL,玩转SQL开发等功能!本教程介绍如何在AnalyticDB MySQL中,一键加载内置数据集,并基于自动生成的查询脚本,运行复杂查询语句,秒级生成查询结果。
阿里云云原生数据仓库AnalyticDB MySQL版 使用教程
云原生数据仓库AnalyticDB MySQL版是一种支持高并发低延时查询的新一代云原生数据仓库,高度兼容MySQL协议以及SQL:92、SQL:99、SQL:2003标准,可以对海量数据进行即时的多维分析透视和业务探索,快速构建企业云上数据仓库。 了解产品 https://www.aliyun.com/product/ApsaraDB/ads
相关文章
|
SQL 自然语言处理 关系型数据库
每日一博 - 闲聊SQL Query Execution Order
每日一博 - 闲聊SQL Query Execution Order
57 0
|
19天前
|
SQL 关系型数据库 MySQL
这样的SQL执行为什么不会报错?optimizer_trace深度历险
【10月更文挑战第12天】本文探讨了一条看似错误但实际上能成功执行的SQL语句,通过开启MySQL的优化器追踪功能,详细分析了SQL的执行过程,揭示了子查询被优化器解析为连接操作的原因,最终解释了为何该SQL不会报错。文章不仅增进了对SQL优化机制的理解,也展示了如何利用优化器追踪解决实际问题。
|
SQL Java Spring
【MybatisPlus异常】The SQL execution time is too large, please optimize
【MybatisPlus异常】The SQL execution time is too large, please optimize
311 0
【MybatisPlus异常】The SQL execution time is too large, please optimize
|
3月前
|
SQL 测试技术
预训练模型STAR问题之SST任务上下文SQL的问题如何解决
预训练模型STAR问题之SST任务上下文SQL的问题如何解决
|
6月前
|
存储 分布式计算 数据可视化
实时数仓 Hologres产品使用合集之报错:ORCA failed to produce a plan : PlStmt Translation: Group by key is type of imprecise not supported如何解决
实时数仓Hologres是阿里云推出的一款高性能、实时分析的数据库服务,专为大数据分析和复杂查询场景设计。使用Hologres,企业能够打破传统数据仓库的延迟瓶颈,实现数据到决策的无缝衔接,加速业务创新和响应速度。以下是Hologres产品的一些典型使用场景合集。
387 0
SAP QM 执行事务代码QS51维护使用决策的选择集,系统报错 – Transaction no longer valid for catalog ‘3’ -
SAP QM 执行事务代码QS51维护使用决策的选择集,系统报错 – Transaction no longer valid for catalog ‘3’ -
SAP QM 执行事务代码QS51维护使用决策的选择集,系统报错 – Transaction no longer valid for catalog ‘3’ -
SAP QM初阶执行事务代码QDB1,报错- Sampling procedure NM000001 has no sampling scheme-
SAP QM初阶执行事务代码QDB1,报错- Sampling procedure NM000001 has no sampling scheme-
SAP QM初阶执行事务代码QDB1,报错- Sampling procedure NM000001 has no sampling scheme-
SAP QM中阶执行事务代码QDB1,报错- Inspection severity 001 AQL 0.650 not in sampling schema A01-
SAP QM中阶执行事务代码QDB1,报错- Inspection severity 001 AQL 0.650 not in sampling schema A01-
SAP QM中阶执行事务代码QDB1,报错- Inspection severity 001 AQL 0.650 not in sampling schema A01-
|
分布式计算 Spark
【spark系列10】spark logicalPlan Statistics (逻辑计划阶段的统计信息)
【spark系列10】spark logicalPlan Statistics (逻辑计划阶段的统计信息)
225 0
|
存储 机器学习/深度学习 算法
MonetDB/X100: Hyper-Pipelining Query Execution 论文解读
这是关于MonetDB执行引擎的一篇paper,总体分为了2个部分,第一部分主要讲了下modern cpu的工作原理并给出了一个TPC-H Q1的例子,从这部分中我们便可以清晰的看到为什么向量化的执行方式如此有意义。第二部分则主要介绍了MonetDB X/100这个新的向量化执行引擎。这篇paper被引用的极为广泛,启发了后续很多列存数据库在执行引擎上的设计思路。个人感觉第一部分尤其有意义,如果想入门下列存/向量化执行,看看第一部分应该就有些概念了。
812 0
MonetDB/X100: Hyper-Pipelining Query Execution 论文解读