数据库查询执行

Query Execution

Processing Model

数据库管理系统的处理模型定义了系统怎样执行一个查询计划

方法:

  1. 迭代模型
  2. 物化模型
  3. 矢量化/批量化模型

Iterator Model

每次查询执行一个Next()函数

  • 在每次调用时,该operator返回单个元组,如果没有更多元组,则返回空标记。
  • 该operator实现一个循环,在其子级上调用 Next() 以检索其元组,然后处理它们。
    也叫做Volcano(火山)或者Pipeline(流水线)模型

一些operator必须阻塞,直到他们的子级发出所有元组

Iterator Model的优点是简单、灵活、易于实现,每个迭代器可以独立地完成自己的逻辑,不需要关心其他迭代器的细节。而且,这种模型可以支持流水线执行(pipelined execution),即在一个迭代器还没有处理完所有的输入数据之前,就可以将部分结果输出给上游的迭代器,从而提高查询效率。

Iterator Model的缺点是性能较低,因为每次只处理一个元组,会造成大量的函数调用开销和数据移动开销。而且,一些操作(如连接、子查询、排序等)可能会阻塞流水线执行,导致查询延迟增加。为了解决这些问题,一些数据库系统采用了其他的查询处理模型,如物化模型(Materialization Model)和向量化模型(Vectorized Model)

Materialization Model

每个运算符同时处理其所有输入,然后立即发出其输出。

  • 运算符将其输出“具体化”为单个结果。
  • DBMS 可以下推提示(例如 LIMIT)以避免扫描太多元组。
  • 可以发送具体化行或单个列

输出可以是整个元组 (NSM) 或列的子集 (DSM)。

更适合 OLTP 工作负载,因为查询一次仅访问少量元组。

  • 降低执行/协调开销
  • 更少的函数调用

不适合具有大量中间结果的 OLAP 查询。

Materialization Model是一种数据库查询处理的模型,它的特点是每个运算符(operator)在处理完所有的输入数据后,将所有的结果一次性输出给上游的运算符,而不是像迭代模型(Iterator Model)那样每次输出一个元组(tuple)。这种模型也称为批处理模型(Batch Model),因为它将数据分成批次进行处理¹²。

Materialization Model的优点是可以减少函数调用的开销,避免频繁地切换上下文。这种模型更适合OLTP(联机事务处理)负载,因为这些查询每次只访问小规模的数据,只需要少量的函数调用²³。

Materialization Model的缺点是可能会增加内存占用和数据移动的开销,因为每个运算符都需要将结果完全物化(materialize)到内存中,而不是像流水线模型(Pipeline Model)那样只需要部分结果。而且,这种模型不能利用流水线执行(pipelined execution)的优势,即在一个运算符还没有处理完所有的输入数据之前,就可以将部分结果输出给上游的运算符,从而提高查询效率¹²。

Vectorized Model

类似于迭代器模型,其中每个运算符实现一个 Next() 函数
不同之处:每个运算符发出一批元组而不是单个元组。

  • 运算符的内部循环一次处理多个元组。
  • 批次的大小可能因硬件或查询属性而异。

OLAP 查询的理想模型,因为它大大减少了每个运算符的调用次数。可以更轻松地使用矢量化 (SIMD) 指令来处理批量元组。

Vectorized Model是一种数据库查询处理的模型,它的特点是每个运算符(operator)在处理数据时,不是按照元组(tuple)为单位,而是按照向量(vector)为单位。向量是一种列式的数据结构,它可以存储多个元组的同一属性值。每次调用next()方法,运算符会返回一个向量,而不是一个元组。这种模型也称为批处理模型(Batch Model),因为它将数据分成批次进行处理。

Vectorized Model的优点是可以提高CPU的利用率,减少函数调用和数据移动的开销,利用SIMD指令进行并行计算,避免类型转换和分支预测等影响性能的因素。这种模型更适合OLAP(联机分析处理)负载,因为这些查询每次需要访问大规模的数据,可以充分发挥向量化的优势。

Vectorized Model的缺点是可能会增加内存占用和数据拷贝的开销,因为每个运算符都需要将向量完全物化(materialize)到内存中,而不是像流水线模型(Pipeline Model)那样只需要部分结果。而且,这种模型需要对运算符进行代码生成(code generation),以适应不同类型和长度的向量

Plan Processing Direction

处理方向决定了系统是从哪个节点开始执行查询计划,以及数据是如何在树中流动的。主要有两种处理方向:

  1. 从上到下(Top-to-Bottom):系统从根节点开始执行查询计划,并从其子节点“拉”数据上来。数据总是随着函数调用而传递。这种方式适合迭代模型和物化模型
  2. 从下到上(Bottom-to-Top):系统从叶子节点开始执行查询计划,并将数据推送给其父节点。数据可以直接写入父节点的缓存或寄存器中,而不需要函数调用。这种方式适合向量化模型

Access Methods

访问方法是 DBMS 访问存储在表中的数据的方式。在关系代数中未定义。

三个方法

  1. Sequential Scan
  2. Index Scan (many variants)
  3. Multi-Index Scan

Sequential Scan

对于表中的每个页

  1. 从缓冲池中检索
  2. 迭代每个元组并检查是否包含它。

DBMS 维护一个内部游标,用于跟踪它检查的最后一个页面/槽。

数据库管理系统中的顺序扫描(Sequential Scan)是一种查询处理的方法,它将每一行数据按照存储的顺序依次读取,并检查是否满足查询条件。顺序扫描可以用于任何表或索引,不需要额外的空间或维护开销,也不受数据分布或选择度的影响。

顺序扫描的优点是简单、通用、稳定,对于小表或高选择度的查询,顺序扫描可能是最快的方法。而且,顺序扫描可以利用操作系统的缓存机制,提高读取效率。

顺序扫描的缺点是性能较低,因为它需要读取整个表或索引的所有数据,即使其中只有少数数据满足查询条件。对于大表或低选择度的查询,顺序扫描可能会造成大量的磁盘I/O和CPU开销,降低查询性能。

为了优化顺序扫描,一种常用的技术是数据跳跃(Data Skipping),它的原理是在写入数据时,收集每个表文件或分区的某些列的统计信息(如最小值、最大值、计数等),并在查询时利用这些信息来判断哪些表文件或分区不包含满足查询条件的数据,从而跳过不必要的读取操作,减少扫描的数据量。

数据跳跃的优点是可以显著提高查询性能,尤其是对于大规模、列式、分区的数据存储格式(如Parquet、Delta Lake等),数据跳跃可以有效地减少磁盘I/O和CPU开销,提高查询效率。

数据跳跃的缺点是需要额外的空间和维护开销,因为它需要在写入数据时收集和存储统计信息,并在更新或删除数据时维护这些信息。而且,数据跳跃的效果取决于数据的布局和分布,以及查询中的过滤条件。为了提高数据跳跃的效果,一种常用的方法是使用Z-Ordering技术,它是一种将相关信息聚集在同一组文件中的方法,可以增强数据跳跃算法的局部性

Index Scan

数据库管理系统中的索引扫描(Index Scan)是一种查询处理的方法,它利用索引结构(如B+树、哈希表等)来快速定位满足查询条件的数据。索引扫描可以根据索引的类型和查询的条件,分为不同的子类,如:

  • 索引范围扫描(Index Range Scan):对索引进行有序的扫描,从满足查询条件的最小值开始,到最大值结束。这种扫描适用于有范围条件的查询
  • 索引唯一扫描(Index Unique Scan):对唯一索引进行精确的匹配,找到满足查询条件的唯一记录。这种扫描适用于有等值条件的查询。
  • 索引全扫描(Index Full Scan):对整个索引进行顺序或逆序的扫描,不需要访问表数据。这种扫描适用于只需要返回索引列的查询。
  • 索引反向扫描(Index Backward Scan):对索引进行逆序的扫描,从满足查询条件的最大值开始,到最小值结束。这种扫描适用于有降序排序或降序范围条件的查询。
  • 索引跳跃扫描(Index Skip Scan):对复合索引进行部分匹配的扫描,跳过不满足查询条件的前导列。这种扫描适用于有非前导列条件的查询
    索引扫描的优点是可以提高查询效率,减少磁盘I/O和CPU开销,利用索引结构的特性进行快速查找和排序。而且,索引扫描可以支持流水线执行(pipelined execution),即在一个运算符还没有处理完所有的输入数据之前,就可以将部分结果输出给上游的运算符。

索引扫描的缺点是需要额外的空间和维护开销,因为它需要在创建和更新数据时维护索引结构。而且,索引扫描的效果取决于数据的分布和选择度,以及查询中的过滤和排序条件。为了提高索引扫描的效果,一种常用的方法是使用合适类型和顺序的复合索引,以覆盖更多的查询场景。

Multi-Index Scan

数据库管理系统中的多索引扫描(Multi-Index Scan)是一种查询处理的方法,它利用多个索引(包括同一个索引的多次使用)来处理无法由单个索引扫描实现的情况。多索引扫描可以在多个索引扫描之间形成AND和OR条件,从而满足查询的需求。例如,一个查询条件如WHERE x = 42 OR x = 47 OR x = 53 OR x = 99,可以被分解为四个单独的索引扫描,每个扫描使用一个查询子句。这些扫描的结果然后被ORed在一起,产生最终结果。另一个例子是,如果我们有分别对x和y建立的索引,一个可能的实现方式是使用每个索引对应的查询子句,并将索引结果AND在一起,从而确定结果行。

为了实现多索引扫描,系统会扫描每个需要的索引,并在内存中准备一个位图(bitmap),表示表中哪些行满足该索引的条件。然后根据查询的需要,将这些位图进行AND和OR操作。最后,访问并返回实际的表行。表行是按照物理顺序访问的,因为这是位图的布局方式;这意味着原始索引的任何排序都会丢失,因此如果查询有ORDER BY子句,就需要一个单独的排序步骤。出于这个原因,以及每个额外的索引扫描都会增加额外的时间开销,优化器有时会选择使用简单的索引扫描,即使有其他可用的索引也是如此。

多索引扫描的优点是可以处理更复杂的查询条件,提高查询效率,减少磁盘I/O和CPU开销,利用多个索引结构的特性进行快速查找和排序。而且,多索引扫描可以支持流水线执行(pipelined execution),即在一个运算符还没有处理完所有的输入数据之前,就可以将部分结果输出给上游的运算符。

多索引扫描的缺点是需要额外的空间和维护开销,因为它需要在创建和更新数据时维护多个索引结构。而且,多索引扫描的效果取决于数据的分布和选择度,以及查询中的过滤和排序条件。为了提高多索引扫描的效果,一种常用的方法是使用合适类型和顺序的复合索引,以覆盖更多的查询场景。

Modification Queries

修改数据库的操作(INSERT、UPDATE、DELETE)负责修改目标表及其索引。

  • 约束检查可以立即在运算符内部发生,也可以推迟到稍后的查询/事务中。

这些运算符的输出可以是记录 ID 或元组数据

Update/Delete

  • 子运算符传递目标元组的记录 ID
  • 必须跟踪先前见过的元组。

Insert

  • 在运算符内部物化元组
  • 运算符插入从子运算符传入的任何元组。

Parallel VS Distributed

数据库分散在多个资源中 以改进 DBMS 的不同方面。对于应用程序而言,无论物理组织如何,都显示为单个逻辑数据库实例。单资源 DBMS 的 SQL 查询应该在并行或分布式 DBMS 上生成相同的结果。

Parallel DBMS

  • 资源在物理上彼此接近。
  • 资源通过高速互连进行通信。
  • 通信被认为是廉价且可靠的。

Distributed DBMS

  • 资源可能彼此相距较远
  • 资源使用较慢的互连进行通信。
  • 沟通成本和问题不容忽视。

Process Model

DBMS 的流程模型定义了系统的架构如何支持来自多用户应用程序的并发请求

Worker 是 DBMS 组件,负责代表客户端执行任务并返回结果。

方法

  1. Process per DBMS Worker
  2. thread per DBMS Worker
  3. Embedded DBMS

Process per DBMS Worker

每个工作进程都是一个单独的操作系统进程。

  • 依赖操作系统调度程序
  • 对全局数据结构使用共享内存
  • 进程崩溃不会导致整个系统瘫痪。

Thread Per Worker

具有多个工作线程的单个进程。

  • DBMS(大部分)管理自己的调度
  • 可以使用也可以不使用调度程序线程。
  • 线程崩溃(可能)会杀死整个系统。

Embedded DBMS

DBMS 与应用程序运行在同一地址空间内。 应用程序(主要)负责线程和调度。

Process Models

多线程架构的优点:

  • 每次上下文切换的开销更少。
  • 不必管理共享内存。

每个工作线程模型并不意味着 DBMS 支持查询内并行性。

Inter VS intra-Query Parallelism

Inter-Query : 同时执行多个不同的查询,提高吞吐量并减少延迟
通过允许同时执行多个查询来提高整体性能。

如果查询是只读的,那么这几乎不需要查询之间的显式协调。 如果需要,缓冲池可以处理大部分共享;如果多个查询同时更新数据库,则很难正确执行此操作

Intra-Query : 并行执行单个查询的操作。减少长时间运行的查询的延迟,尤其是 OLAP 查询。
通过并行执行单个查询的运算符来提高单个查询的性能。
从生产者/消费者范式的角度来考虑organization的组织。
每个运算符都有并行版本。可以让多个线程访问集中式数据结构,也可以使用分区来划分工作。

Intra-Query Parallelism

根据不同的并行粒度和方式,可以将intra-query parallelism分为三种方法:

  1. Intra-Operator(Horizontal)
  2. Inter-Operator(Vertical)
  3. Bushy
Intra-Operator

将运算符分解为独立的片段,这些片段对不同的数据子集执行相同的功能。

例如,在关系查询中,如果有一个选择操作(如 WHERE 子句),可以将数据分成多个子集,然后并行执行选择操作。每个并行任务独立处理自己的数据子集,然后将结果合并以生成最终的查询结果。

DBMS 将Exchange运算符插入到查询计划中,以合并/拆分来自多个子/父运算符的结果。

Exchange 运算符是用于在并行执行计划内的不同并行任务之间传递数据的重要组件。Exchange 运算符通常涉及将数据从一个并行任务(例如生产者)传递到另一个并行任务(例如消费者),以便在并行执行计划中协调数据流。Exchange 运算符的三个主要步骤是 gather、distribute 和 repartition。详细介绍这三个步骤:

  1. Gather(收集):
    Gather 步骤是 Exchange 运算符的第一个步骤,它负责从多个并行生产者任务收集数据并将其合并为一个集中的数据流。在这个步骤中,每个并行任务将其产生的数据发送到 Exchange 运算符,该运算符负责汇总所有数据,以便在后续的处理中进行分发或重新分区。Gather 步骤有助于将多个并行任务生成的数据汇总到一个中央位置,以便进行下一步的处理。
  2. Distribute(分发):
    Distribute 步骤是 Exchange 运算符的第二个步骤,它负责将汇总的数据流分发到多个并行消费者任务。在这个步骤中,Exchange 运算符将收集到的数据流拆分为多个部分,并将每个部分发送到不同的并行任务,以便在并行执行计划中进行后续的操作。Distribute 步骤确保数据能够在多个消费者之间均匀分布,以实现负载均衡和并行处理。
  3. Repartition(重新分区):
    Repartition 步骤是 Exchange 运算符的第三个步骤,它负责根据需要重新分区数据流,以便进行后续的处理。在某些情况下,数据的分布可能不适合后续的并行操作,因此需要重新分区。Repartition 步骤可以重新组织数据,使其适合于下游操作的并行处理,同时确保数据的一致性和正确性。
Inter-Operator

在这种方法中,查询计划中的不同操作符可以并行地执行。每个操作符处理不同的查询子任务,并在必要时将结果传递给其他操作符。这种方式适用于一些查询计划,其中存在多个独立的操作,可以在并行的情况下同时执行,而不需要依赖于其他操作的输出。

Bushy

Bushy 并行是一种更为复杂的方法,它涉及将查询计划中的多个操作符以多个并行任务的方式同时执行。与传统的树状查询计划不同,Bushy 并行允许在操作之间创建更复杂的连接和交互。这样可以更充分地利用系统资源,但也可能需要更复杂的调度和协调。

I/O parallelism

I/O parallelism是一种利用多个磁盘或其他存储设备来提高查询性能的技术。它的基本思想是将数据分割成多个子集(segment),并将每个子集存储在不同的磁盘上。这样,当查询需要读取或写入数据时,可以并行地访问多个磁盘,从而减少I/O时间和提高吞吐量。

需要权衡的地方

  1. Multiple Disks per Database
  2. One Disks per Database
  3. One Relation per Database
  4. Split Relation across Multiple Disk

Multi-disk parallelism是一种特殊的I/O parallelism,它是指在一个单一的处理器或线程上使用多个磁盘来执行查询。它的基本思想是将一个磁盘上的数据划分为多个块(block),并将每个块分配给不同的磁盘上的缓冲区(buffer)。这样,当查询需要读取或写入数据时,可以并行地访问多个缓冲区,从而减少I/O时间和提高吞吐量。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值