第十讲 Query Execution Part 1

1 处理模型【Processing Model】

DBMS 的处理模型【Processing Model】定义了系统如何执行【execute】查询计划【Query Plan】。

  • 针对不同的工作负载进行不同的权衡。

方法1:迭代器模型【Iterator Model】
方法2:物化模型【Materialization Model】
方法3:矢量化/批处理模型【Vectorized / Batch Model】

1.1 迭代器模型

迭代器是最简单的模型。他是一种自顶向下的方法。

每个查询计划【Query Plan】的(物理)操作符【Operator】都实现一个 Next() 函数。

  • 在每次调用时,操作符返回单个元组(需要注意的是,这个元组可以是关于列的一个子集,也可以是 Record ID),如果没有更多元组,则返回 eof 标记。
  • 操作符实现一个循环,即查询计划树中的父操作符在在其子节点的操作符上调用 Next() 来检索其输出元组,然后处理它们。

每个操作符的实现还具有 Open() 和 Close() 函数,它们类似于构造函数和析构函数,但这是用于操作符的罢了。
迭代器模型也称为火山模型【Volcano Model】或管道模型【Pipeline Model】。

如今大多数 DBMS 都使用这种方法,,它使得元组流水线【pipeling】成为可能。
许多运算符必须阻塞,直到他们的子操作符发出所有元组,赭红操作符也被称为 Pipeline Breaker:

  • 连接【Joins】,
  • 子查询【Subqueries】
  • 排序【Order By】

使用这种方法可以轻松进行输出控制。比如我们在查询【Query】中添加 LIMIT 10 子句,那么点那个我们的根操作符在迭代了 10 次后就可以停止了,我们不需要再继续调用 Next 了。

迭代器的约束是:我们一次只能处理一个元组,我们通过 Next 获取一个元组,然后可能会去做一些成本很高的操作,如果我们可以批量处理,那么就可以摊销很多的成本。

1.2 物化模型

物化模式是一种自底向上的方法。当父操作符调用子操作符时,他总是生成他可以生成的所有结果,然后上推给它的父擦作符。

每个操作符一次处理所有输入,然后一次发出所有输出。

  • 操作符将其输出“物化”为单个结果。
  • DBMS 可以下推提示【push down hints】(例如 LIMIT)以避免扫描太多元组。
  • 可以发送物化后的行或者单个行。

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

在该模型下,我们经常会用到内链【inline】,比如图中的 S 表假设有亿万数据,我们将所有元组加载到内存,然后一次返回给父操作符,这种方法太愚蠢了,因此我们会将某些操作符进行内联。

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

  • 更低的执行/协调开销。
  • 更少的函数调用/操作符调用

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

1.3 矢量模型

矢量模型就像迭代器模型一样,每个运算符都实现一个 Next() 函数,但是每个操作符发出一批元组而不是单个元组。

  • 每个运算符在内部作循环中,一次处理多个元组来加快速度(由于我们一次可以看到所有的数据,我们可以做一些矢量化操作,比如SIMD)
  • 批次的大小可能因硬件或查询属性而异

矢量化模型非常适合 OLAP 查询,因为它大大减少了每个操作符的调用次数,并使得操最符更轻松地使用矢量化 (SIMD) 指令来处理批量元组。 

1.4 PLAN PROCESSING DIRECTION

方法1:自上而下:

  • 从根开始,从其子节点“提取”数据。
  • 元组总是通过函数调用传递。

方法2:自下而上

  • 从叶节点开始,将数据推送到其父节点。
  • 允许对管道中的缓存/寄存器进行更严格的控制。
  • 更适合动态查询重新优化。

但是,大多数系统都是自顶而下的。

2 访问方法【Access Method】

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

三种基本的访问方法:

  • 顺序扫描【Sequential Scan】
  • 索引扫描【 Index Scan】(许多变体)。
  • 多索引扫描【Multi-Index Scan】

2.1 顺序扫描【Sequential Scan】

对于表中的每一页【Page】:

  • 从缓冲池中检索它
  • 迭代每个元组并检查是否需要包含它

DBMS 维护一个内部游标,用于跟踪它检查过的最后一个页【Page】/槽【SLot】。、

这几乎总是 DBMS 在执行查询时可以做的最糟糕的事情,但它有时候可能是唯一可用的选择(比如当我们没有任何索引时)。
顺序扫描的优化:

  • 预取【Prefetching】
  • 缓冲池绕过【Buffer Pool Bypass】
  • 并行化【Parallelization】
  • 堆聚簇【Heap Clustering】
  • 延迟物化【 Late Materialization】
  • 数据跳过【Data Skipping】
数据跳过

方法1:近似查询【Approximate Queries】(有损)

  • 对整个表的采样子集执行查询以产生近似结果。
  • 示例:BlinkDB、Redshift、ComputeDB、XDB、Oracle、Snowflake、Google BigQuery、DataBricks

方法2:区域地图【Zone Map】(无损)

  • 预先计算每页的列式聚合【Aggregation】,DBMS 首先检查区域地图【Zone Map】来决定是否要访问该页【Page】。
  • 需要在页面大小与过滤器效能之间进行权衡,因为页面越大,数据也就越多,如果在一个有百万数据的大页上,我们根据区域地图算出需要访问该页,但是该页中可能只有一条数据满足查询条件,但是我们不得不扫描完整的页。
  • 示例:Oracle、Vertica、SingleStore、Netezza、Snowflake、Google BigQuery

2.2 索引扫描【 Index Scan】

DBMS 选择一个索引来查找查询【Query】所需的元组。
使用哪个索引取决于(所有这些都是后面章节里会讲,大概是第12讲):

  • 索引包含哪些属性【attribute】
  • 查询【Query】引用哪些属性【attribute】
  • 属性【attribute】的值域
  • 谓词组合【Predicate composition】
  • 索引是否有唯一键或非唯一键

假设我们有一个包含 100 个元组和两个索引的表:
→ 索引1:age
→ 索引2:dept

SELECT * FROM students

WHERE age < 30

AND dept = 'CS'

AND country = 'CHINA'

场景1:30岁以下的有99人,但是CS部门只有2人。 

在该场景下,我们希望可以选择 dept 索引,因为他的选择性更好,可以顾虑更多的数据

场景1:30岁以下的有 2人,但是CS部门有99人。 

在该场景下,我们希望可以选择 age 索引,因为他的选择性更好,可以顾虑更多的数据

2.3 多索引扫描【Multi-Index Scan】

如果 DBMS 可以在一个查询【Query】中使用多个索引:

  • 使用每个匹配的索引计算 Record ID 的集合。
  • 根据查询【Query】的谓词,来组合这些集合(并集与交集)
  • 检索记录并应用剩余的谓词

实现的数据库:

  • DB2 多索引扫描
  • PostgreSQL 位图扫描
  • MySQL 索引合并

SELECT * FROM students

WHERE age < 30

AND dept = 'CS'

AND country = 'CHINA'

继续复用前面的 age 和 dep 的例子:

  • 我们可以使用第一个检索 idx_age 来匹配满足 age < 30 的 Record ID
  • 然后使用第二个检索 idx_dep 来匹配满足 dept = 'CS' 的 Record ID,
  • 取它们 的交集
  • 检索记录,并检查 country = 'CHINA'

可以使用位图【Bitmap】或哈希表【Hash Table】有效地完成集合交集。

3 修改查询【Modification Query】

修改数据库的操作符(INSERT、UPDATE、DELETE)需要负责修改目标表【table】及其索引【index】,约束检查可以立即在操作符内部发生,也可以推迟到稍后的查询【Query】/事务【Transction】中。


这些运算符的输出可以是 Record ID 或元组数据(即 RETURNING)。

UPDATE/DELETE:

  • 子操作符传递目标元组的 Record ID
  • 必须追踪每一个先前看到过的元组(下面例子里会讲,这也是万圣节问题的解决方案)。

INSERT:

  • 选择1 :在操作符内部物化元组
  • 选择2:操作符插入从子操作符传入【Pass In】的任何元组。

例子:

1️⃣ 假设我们有一张perople表,表中记录了薪水

2️⃣ 现在我想对所有薪水小于 1100 的人作一次 100 元的薪水普调,那么现在我的更新操作符会调用它的子操作符的 Next 方法,该子操作符执行一个索引扫描,以超出所有薪水小于 1100 的工人

 

3️⃣ 在索引扫描中,我们跟随游标遍历数据,并将满足条件的元组返回给父操作符

4️⃣ 然后父操作符将它从索引内删除,然后插入一条更新后的索引


5️⃣ 然后索引游标继续滑动,但是我们会查到刚才插入的那条数据

这就是著名的万圣节问题【HALLOWEEN PROBLEM】,即:更新操作更改元组的物理位置,导致扫描操作符多次访问该元组的异常。

  • 可能发生在聚簇表或索引扫描上。

IBM 研究人员于 1976 年万圣节在 System R 上工作时首次发现。
解决方案:跟踪每个查询【QUery】中修改的 Record ID。 

4 表达式评估【Expression Evaluation】

DBMS 将 WHERE 子句表示为表达式树【Expression Tree】。我们前面看到查询计划【QUery Plan】是一颗关于操作符的数,在每个操作符内部依然可以是树结构。

表达式树中的节点代表不同的表达式类型:

  • 比较(=、<、>、!=)
  • 合取 (AND)、析取 (OR)
  • 算术运算符(+、-、*、/、%)
  • 常数值
  • 元组属性引用【Tuple Attribute Reference】

例子:

1️⃣ 下面是我们要执行的 Prepared 语句,我们调用execute执行它

 2️⃣ 下面是该SQL中的表达式树:

以这种方式评估谓词的速度其实很慢,DBMS 遍历树,对于它访问的每个节点,它必须弄清楚操操作符需要做什么。

我们来考虑这个谓词:WHERE S.val=1

更好的方法,或者说是优化吧,就是直接计算表达式,回想一下 JIT 编译,Postgre 中就有这个特性,它会将表达式部分内联编译(set jit = 'on')。

5. Schedule

到目前为止,我们基本上已经从数据流【data flow】的角度了解了查询处理模型【query processing model】。
控制流【conrol flow】隐含在处理模型【processing model】中。 我们可以使用调度程序【scheduler】使控制流更加明确。
数据库论文中通常不会讨论查询调度程序【scheduler】。 我们将看看 Quickstep(学术)项目中做了什么。 基于允许数据流和控制流之间的频繁切换。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

创建和启动线程

概述 Java语言的JVM允许程序运行多个线程&#xff0c;使用java.lang.Thread类代表线程&#xff0c;所有的线程对象都必须是Thread类或其子类的实例。 Thread类的特性 每个线程都是通过某个特定Thread对象的run()方法来完成操作的&#xff0c;因此把run()方法体称为线程执行体。…

数据结构之堆底层实现的循序渐进

题外话 把没写的都补回来! 正题 堆 概念 堆是一棵完全二叉树&#xff0c;因此可以层序的规则采用顺序的方式来高效存储&#xff0c; 大根堆:指根结点比左右孩子都大的堆 小根堆:指根结点比左右孩子都小的堆 性质 1.堆中某个节点的值总是不大于或不小于其父节点的值 2…

CCIE-14-MPLS_and_BGP

目录 实验条件网络拓朴 环境配置开始配置配置MPLSR1访问R6检测结果R6访问R1检测结果 实验条件 网络拓朴 环境配置 在我的资源里可以下载&#xff08;就在这篇文章的开头也可以下载&#xff09; 开始配置 R1<->R2&#xff1a;EBGP R2<->R5&#xff1a;IBGP&…

蓝桥杯备考3

P8196 [传智杯 #4 决赛] 三元组 题目描述 给定一个长度为 n 的数列 a&#xff0c;对于一个有序整数三元组 (i,j,k)&#xff0c;若其满足 1≤i≤j≤k≤n 并且&#xff0c;则我们称这个三元组是「传智的」。 现在请你计算&#xff0c;有多少有序整数三元组是传智的。 输入格式…

小米手机澎湃OS,不Root查看电池健康

首先&#xff0c;在键盘拨号界面&#xff0c;输入*#*#284#*#*&#xff0c;会调用问题反馈APP来生成当前系统的故障日志&#xff0c;如果提示你需要授权什么就点确认 稍等几分钟&#xff0c;会得到一个压缩包&#xff0c;保存在目录MIUI/debug_log下 这里为了方便&#xff0c;我…

肖恩带你学C语言·文件操作(上)

1. 为什么使用文件 如果没有文件&#xff0c;我们写的程序的数据是存储在电脑的内存中&#xff0c;如果程序退出&#xff0c;内存回收&#xff0c;数据就丢失了&#xff0c;等再次运行程序&#xff0c;是看不到上次程序的数据的&#xff0c;如果要将数据进行持久化的保存&…

打造自然资源“一张图”管理平台,推动生态文明建设新篇章

在信息化时代的浪潮下&#xff0c;自然资源管理正面临着前所未有的挑战与机遇。传统的资源管理模式已经难以满足当前生态环境保护与经济发展的双重需求&#xff0c;我们需要一个全新的平台&#xff0c;一个集信息集成、智能分析、决策支持于一体的自然资源“一张图”管理平台。…

数据可视化-地图可视化-Python

师从黑马程序员 基础地图使用 基础地图演示 视觉映射器 具体颜色对应的代码可以在http://www.ab173.com/中查询RGB颜色查询对照表 from pyecharts.charts import Map from pyecharts.options import VisualMapOpts#准备地图对象 mapMap() #准备数据 data[("北京",…

c语言结构体变量和结构体数组的练习(自用版)

结构体变量注释和结构体数组练习&#xff08;已注释&#xff09;代码&#xff1a; #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> struct Student {char name[20];int age;char sex;float score;char addr[30]; };int main() {//练习结构体变量struct Student s…

SSL/TLS:网络安全中的基石

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

c# wpf LiveCharts 简单试验2

1.概要 1.1 说明 1.2 要点 1.2.1 添加命名控件 xmlns:lvc"clr-namespace:LiveCharts.Wpf;assemblyLiveCharts.Wpf" 1.2.2 图片控件 <lvc:CartesianChart Name"chart" LegendLocation"Right"/> 1.3 代码文件引用 using LiveCharts…

YOLOv5实战记录05 Pyside6可视化界面

个人打卡&#xff0c;慎看。 指路大佬&#xff1a;【手把手带你实战YOLOv5-入门篇】YOLOv5 Pyside6可视化界面_哔哩哔哩_bilibili 零、虚拟环境迁移路径后pip报错解决 yolov5-master文件夹我换位置后&#xff0c;无法pip install了。解决如下&#xff1a; activate.bat中修改…

刷题之Leetcode844题(超级详细)

844.比较退格的字符串 844. 比较含退格的字符串https://leetcode.cn/problems/backspace-string-compare/ 给定 s 和 t 两个字符串&#xff0c;当它们分别被输入到空白的文本编辑器后&#xff0c;如果两者相等&#xff0c;返回 true 。# 代表退格字符。 注意&#xff1a;如…

5G网络架构及技术(二):OFDM一

ToDo: 等把这些讲义看完后得单开一个文章整理思维导图   该部分由于内容比较重要&#xff0c;OFDM是5G物理层的基础&#xff0c;但学习时直接跳到5G OFDM去看它的那些参数设置感觉没什么意义&#xff0c;还得从发展的角度进行学习&#xff0c;先从最先用到OFDM的WiFi协议开始…

CSS-属性

&#x1f4da;详见 W3scholl&#xff0c;本篇只做快速思维索引。 CSS 背景 用于定义元素的背景效果。 background-colorbackground-imagebackground-positionbackground-repeatbackground-attachment background-color background-color 属性指定元素的背景色。 h1 {back…

专题【链表】【考试题】刷题日记

题目列表 考试题&#xff08;22题&#xff09; 2024.04.04 146. LRU 缓存 707. 设计链表 138. 随机链表的复制 160. 相交链表 622. 设计循环队列 109. 有序链表转换二叉搜索树 460. LFU 缓存 355. 设计推特 725. 分隔链表 2487. 从链表中移除节点 日常复习题 876. 链表的中…

机器学习(理论第一课)

一、理解人工智能、机器学习、深度学习、强化学习&#xff1f; 人工智能、机器学习和深度学习之间存在递进关系&#xff0c;它们的覆盖范围逐层递减。 **人工智能&#xff08;Artificial Intelligence&#xff0c;AI&#xff09;**是最宽泛的概念&#xff0c;旨在研究、开发用于…

好物周刊#49:字幕交流网站

https://yuque.com/cunyu1943 村雨遥的好物周刊&#xff0c;记录每周看到的有价值的信息&#xff0c;主要针对计算机领域&#xff0c;每周五发布。 一、项目 1. Starship 轻量、迅速、可无限定制的高颜值终端&#xff0c;可用于各种 Shell 的提示符。 2. spring cloud shop …

Web3 游戏周报(3.24-3.30)

【3.24-3.30】Web3 游戏行业动态&#xff1a; Web3 开发平台 Mirror World 在 Solana 上推出首个游戏 rollup 链 NFT 卡牌游戏 Parallel 完成 3,500 万美元融资&#xff0c;Solana Ventures 等参投 加密游戏开发公司 Gunzilla Games 完成 3,000 万美元融资 Telegram 游戏 No…

【C语言自定义类型之----结构体,联合体和枚举】

一.结构体 1.结构体类型的声明 srruct tag {nemer-list;//成员列表 }varible-list;//变量列表结构体在声明的时候&#xff0c;可以不完全声明。 例如&#xff1a;描述一个学生 struct stu {char name[20];//名字int age;//年龄char sex[20];//性别 };//分号不能省略2.结构体…