数据库内核杂谈阅读笔记

2023-11-06

数据库内核杂谈-InfoQ

简单数据库实现

  • 一个sql查询语句,可以拆分成原子operator的叠加,把operator组建成operator tree,自底向上执行最终得到结果
  • Mysql和Postgres中执行EXPLAIN SQL_STMT可以打印生成的operator tree

存储

  • 分离元数据和数据的存储
  • 修改文件造成较大的读写负担,可以使用slot_table记录信息,并且使用append only的形式(对于数据文件的修改也用append only的形式),在读取数据时先读取slot_table,然后逆序逆序读取所有行的标注信息。随着数据文件增加,使用vacuum操作(compact),读取数据文件和slot_table根据标注把有效的数据行写回新的文件。
  • 不适用明文而使用raw byte来存储数据配合高效的编码和解码算法
  • 类似雪花模型,需要存多且大的实体表,但是语句只需要读取相关的几个属性。可以使用列村而不是行存。在

索引优化

  • 哈希索引:建立哈希表

  • B树索引:建立B/B+树

    优化:对于经常查询的列可以把列的数据直接存储在索引中,省去读取文件的时间

    缺点:高并发环境下需要加锁,可以用skip list代替

两种索引相比更建议使用B树索引,且B树索引得到的结果对于索引列是有序的

Because of the limited utility of hash indexes, a B-tree index should generally be preferred over a hash index. We do not have sufficient evidence that hash indexes are actually faster than B-trees even for = comparisons. Moreover, hash indexes require coarser locks.

  • 位图索引:适合基数小的列来做索引

    例:

    sex: bitmap
    male: 10001111
    female: 01110000
    

    查询时只需要和位图做与操作,选出结果为1的即可

    局限:只适合列基数小的,且不适合高并发环境

执行模式

用户输入SQL语句

Parsing

通过编译器把语句编译(parsing)成抽象的语法树

Binding

负责将语法树和数据库的metadata结合,附上语义。自底向上对整颗语法树的节点依次检查,同时在节点绑定元数据,最终生成含有语义的语法树。

binding完成之后,SQL语句就算编译通过。

Optimizing

给定语法树,首先生成一个逻辑执行树,执行树上的每一个节点称为逻辑操作符。对应每个逻辑操作符,扩展出所有的物理操作符,逻辑操作符表示某个功能,物理操作符则说明用什么方法来实现这个功能, 可能有多个物理执行树。下一步在多个物理执行树中选出最优的一个,这步操作比较复杂。

Executing

从执行树底层开始依次执行。

执行器的执行模式:

  • materialization模式,代码运行时自底向上,每个节点process只需要运行一次,一次性处理全部输入
  • iterator model/volcano model,第一种模式可能面临OOM(out of memory)的问题,使用类似流系统的运行模式(其实是流系统借鉴了数据库的运行模式),每个操作符既是producer,又是consumer。但对于一些操作,如sort数据会阻塞等待所有数据,需要spill to disk操作。
  • vectorization model/batch model:一批一批数据处理,

排序和聚合

排序

需要排序的sql语句:Order By, Distinct

实现:

  • 外部归并排序(external merge sort) 用读写数据的次数衡量算法
  • 读取B+树的索引结果

聚合

  • 单项聚合:聚合之后的结果是一个单项值

    只需要保存聚合中间值,根据新输入值不断更新即可,且内存消耗不大

  • 组队聚合:结合group by的聚合

    使用排序或者哈希表来实现

    遇到内存不够大的问题,使用外部哈希表,借助文件系统暂存数据

JOIN

Table A: M个block m个row

Table B: N个block n个row

Join基于equally join

Join算子实现

  • NestedLoopJoin

  • SortMergeJoin

    类似Merge的过程,每个表维护一个指针,根据Join的键做排序

    时间复杂度 M+N+2M*log2M + 2N *log2N

  • HashJoin

    时间是线性的,在绝大多数情况下,性能是最佳的

优化器

优化运行时间

Query Rewrite

在这一步对原来的语法树进行等价的语义重写,优化掉无效或者无意义的操作

常见规则

  • Projections push down,把需要哪些column直接下推到叶节点的table scan,可以减少数据的大小并提高scan的速度
  • Predicates push down,把filter predicates往下推送
  • Impossible/Unnecessary Predicates: 计算Predicates的值,如果恒为false( where 1 = 0 )直接返回空集,如果恒为true,直接去掉predicates
  • Merge Predicates:优化器把多个predicates合并
  • Join elimination

Heuristic approach

优化器如何决定join的顺序来找到最优解?

n个表join的搜索空间是4n,首先要减小搜索空间。

在最早的Valcano Optimizer中,提出了对于Join Order,只考虑left-deep-tree

Cardinality Estimation

用于预测哪两个表join之后的cardinality比较小,来决定join ordering。帮助决定logical operator

Selection cardinality:

​ SC(P,R)表示当predicate是P的时候,对于表R,最后大约会有多少条row输出

​ 需要知道表的一些基本的元信息: 如总行数,表中的每个column有多少个distinct value

​ 数据库会不定期的自动更新每个表以及每个column的统计信息

Join cardinality:

SEL * FROM R1, R2 WHERE R1.a = R2.a;

​ 公式: JC(R1, R2, R1.a = R2.a) = N_R * N_S / max(V(a, R), V(a, S))

V(a,R)表示R中的column a,一共有多少个distinct value

同时还需要知道数据的分布情况,常见的统计数据分布的方法是使用Histogram

Cost Model

不同的算子有不同的实现方法,使用Cost Model决定

每一个operator,有一个cost formula

同一个算子的不同实现方法,可以根据实际语句计算cost formula的值,选择cost比较小的

对于整个logical operator tree, 每个logical operator的选择不是局部最优的问题,使用DP解决

事务、隔离、并发

这部分笔者比较熟悉,不再详细记录

单机数据库扩展到分布式

数据库内核杂谈(十三):如何把一个单机数据库扩展成分布式数据库-InfoQ

使用一个leader节点,多个worker节点的架构,leader节点处理客户端的请求,并且对语句进行编译、绑定和优化。仅leader节点需要有优化器的实例,所有节点都会有执行器的实例。

和普通算子相比,分布式算子是节点之间的相互通信,需要RPC调用,调用的成本相对更高。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

数据库内核杂谈阅读笔记 的相关文章

随机推荐

  • 【已解决】使用Appium Inspector及uiautomatorviewer无法定位浮窗内元素

    1 问题描述 当开启一个应用的画中画模式时 将会调出浮窗 此时使用Appium Inspector及uiautomatorviewer均无法定位浮窗内元素 只能对浮窗底层的Activity进行元素定位 Appium Inspector ui
  • chatgpt的第一次尝试

    openai最近很火 火的公司的市场部门都已经用chatgpt来写市场方案和产品方案了 是市场部总监在一个公寓里住着 两人昨天交流了一些有关chatgpt的认识 在市场部的影响下 开始了chatgpt的第一次试用 我试用了2个主题 一个是有
  • OCR模型DBNet-------《Real-time Scene Text Detection with Differentiable Binarization》论文,模型,代码解剖

    首先 我先对DBNet的论文进行重点翻译解释说明 之后再对整个模型进行解剖 最后再对官方源码的实现方法 关键代码进行分析 所以篇幅也比较长 之间会附带一些例子说明 让你更深刻的了解DBNet 论文解析 Abstract 基于语义分割的文本检
  • 谷歌裁员1.2万,幸存员工崩溃哭泣

    1 月 20 日 谷歌母公司Alphabet首席执行官桑达尔 皮查伊宣布裁员 裁员人数相当于公司全球员工总数的 6 左右 1 2 万人 2022 2023 中国开发者大调查 重磅启动 欢迎扫描下方二维码 参与问卷调研 更有 iPad 等精美
  • 正常计算机的c盘空间多大,电脑C盘应该留多大空间?

    机械硬盘 不管是500G 1TB 2TB 4TB win7 还是win10系统统一60G就行 C盘大小为 60G 固态硬盘 两种情况 一种是120G 一种是240G及以上 120G硬盘 C盘为120G 整个硬盘为一个区 240硬盘及以上 C
  • 服务器配置openssl支持 https 访问

    一 Windows apache 下 软件是xampp 说明 部分参考 http blog sina com cn s blog 5d7dbbdd0101042n html 首先要载入 mod ssl 1 将证书生成的配置文件 http t
  • MFC---CComboBox控件添加字符串函数InsertString

    InsertString 在列表的指定位置插入一项 需使用成员函数InsertString 函数有两个参数 第一个参数为索引号 设定为 1时 项目条被插入到列表的末尾 第二个参数与AddString 函数的唯一参数相同 为代表项目条中内容的
  • python中字典考题_python 字典一些常见的魔法方法以及遇到的面试题

    一 字典介绍 dict 类型不但在各种程序里广泛使用 它也是 Python 语言的基石 模块的命名空间 实例的属性和函数的关键字参数中都可以看到字典的身影 跟它有关的内置函数都在 builtins dict 模块中 正是因为字典至关重要 P
  • 对标大厂标准,C站(CSDN)软件工程师能力认证正式上线

    2021年3月1日 中国专业IT开发者社区CSDN 以下简称C站 正式推出 C站软件工程师能力认证 该认证与国际标准接轨 面向全球IT开发者学习成长 同时具备标准全开源 系统化学习 真实业务场景 完全上机实操 所有过程留痕 存档不可篡改等特
  • 【Leetcode】61. 旋转链表

    题目描述 给你一个链表的头节点 head 旋转链表 将链表每个节点向右移动 k 个位置 题解 旋转链表 找倒数第k个节点 翻转前后链表 执行用时 0 ms 在所有 Java 提交中击败了100 00 的用户 内存消耗 37 8 MB 在所有
  • 重磅, GPT 4.0 API 全面开放使用!普通人也能用上 4.0 了 !

    伴随着人工智能领域的迅猛发展 GPT 4 0作为一款关键的智能模型 备受国内开发者和企业的瞩目 本文旨在为您提供详实的指南 帮助您在国内顺利获取并使用GPT 4 0 API 从而踏上智能应用创新之路 我们将为您提供一步一步的操作步骤和必要的
  • 【ts】数组、联合数据类型、类型推论

    一 ts约束数组 1变量 类型 let arr Number 1 3 3 4 arr push 1 arr push he 不能添加数组中没有约束的类型 2 数组泛型 变量 Array lt 类型 gt let arr Array
  • DasViewer加载大疆智图、CC等三维模型无空间坐标的解决方法

    对于大疆智图处理生成的terra osgbs文件夹下的三维模型包含了带有空间参数的metadata xml文件 利用DasViewer打开Model osgb模型文件 显示比较模糊 不能够达到实际应用的目的 我是利用转格式工具进行格式转换生
  • python 执行js脚本报错CryptoJS is not defined

    直接在js代码加上一行定义CryptoJS就行了 function encrypt e const CryptoJS require crypto js var b bGVhcm5zcGFjZWFlczEyMw var a new Base
  • 【Spring实战】—— 7 复杂集合类型的注入

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 之前讲解了Spring的基本类型和bean引用的注入 接下来学习一下复杂集合类型的注入 例如 List Set Map等 对于程序员来说 掌握多种语言是基本的技能 我们这里
  • 在本地以Docker方式安装和运行Kafka

    文章目录 在本地以Docker方式安装和运行Kafka 前言 用Bitnami kafka的镜像 用wurstmeister kafka的镜像 启动Kafka 测试创建主题并读 写消息 参考文档 后记 在本地以Docker方式安装和运行Ka
  • discuz7.2漏洞分析

    一 参数的入口 这段话的意思时遍历三种提交的方法 获取参数传递的值 有一个函数是daddslashes 跟进看一下 这段代码的意思是对数据里的每一个字符都进行转义处理 二 漏洞产生的代码在faq php195行 跟进implodeid函数
  • Tomcat安装测试、Eclipse配置Tomcat步骤

    一 安装tomcat并测试 1 1 1到Apache Tomcat官网下载安装包 在选择中间位置的版本较为稳定然后选择对应操作系统的安装包 本次选择8 5版本 1 1 2 解压下载好的安装包即可完成安装 复制Tomcat的安装路径以备下一步
  • 第十七章 C# Action和Func委托 多播 匿名函数 lambda表达式

    一 使用 Action和Func委托 方法的返回类型 和 名字千千万万 无法对每个方法都去定义对应的委托 nt为了方便使用委托 定义了两个泛型委托 Action Action委托表示一个void返回类型的方法 例1 MyDelegate m
  • 数据库内核杂谈阅读笔记

    数据库内核杂谈 InfoQ 文章目录 简单数据库实现 存储 索引优化 执行模式 Parsing Binding Optimizing Executing 排序和聚合 排序 聚合 JOIN 优化器 Query Rewrite Heuristi