自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(93)
  • 收藏
  • 关注

原创 OpenGauss MOT表实现代码走读

本文分析了openGauss中MOT表的实现机制,主要包含三个核心流程:1)读流程通过MOTIterateForeignScan函数实现,利用Mass索引和本地/全局内存查找机制高效获取数据;2)写流程通过MOTExecForeignInsert等函数实现,先在本地内存操作,提交时才通过WriteChanges将数据同步到全局内存;3)创建表时默认生成伪主键索引,若指定主键则替换伪索引。MOT表通过无锁设计、延迟checkpoint等机制实现了高并发读写能力。

2026-07-18 15:58:12 169

原创 openGauss之LLVM代码走读

本文介绍了openGauss数据库如何利用LLVM动态编译技术优化SQL查询性能。通过分析"select col_bool is true from test1"查询案例,文章详细阐述了openGauss的LLVM实现机制:1)在ExecInitCStoreScan阶段将表达式转换为动态生成的中间代码;2)在standard_ExecutorRun阶段将中间代码编译为机器码;3)最终在执行时调用编译后的高效机器码替代原执行流程。该技术通过即时编译频繁执行的代码块,显著提升了向量引擎中数据

2026-07-04 14:58:16 154

原创 openGauss 之gin索引的实现代码走读

本文介绍了openGauss数据库中GIN倒排索引的实现机制。GIN索引以词语为key,对应ctid位置数组为value,适用于关键词搜索场景。文章详细解析了索引插入和查找过程:插入时通过gininsert函数遍历索引键,提取词条后排序去重,再将词与ctid信息存入索引;查找时先提取查询条件,通过B+树定位叶子节点,获取ctid列表后返回匹配元组。实现中采用了词频优先过滤、B+树扫描优化等策略,支持高效的关键词检索。

2026-06-06 20:54:40 203

原创 openGauss 之 索引reindex代码走读

摘要:本文分析了openGauss中三种索引重建方式的实现机制。普通reindex通过加8级锁重建索引;reindex concurrently采用四级锁,通过创建临时索引、数据追平、名称交换等步骤实现不阻塞DML操作;并行reindex则通过设置parallel_workers参数启用多线程扫描堆数据。三种方式在锁级别、并发控制和执行流程上存在显著差异,其中reindex concurrently通过多阶段处理实现了索引重建与业务操作的并行执行。

2026-03-23 22:25:08 53

原创 openGauss之alter table实现流程代码走读

本文分析了openGauss中ALTER TABLE操作的实现流程。其核心是通过创建临时表、逐行转换数据并交换表文件的方式完成表结构变更。具体步骤包括:1)通过ProcessUtilitySlow入口获取表锁;2)根据ALTER类型封装命令;3)创建临时新表并加锁;4)扫描旧表数据,对需要修改的列进行表达式计算;5)将转换后的数据插入临时表;6)最后通过swap_relation_files交换新旧表的文件完成变更。整个过程采用8级排他锁确保数据一致性,分区操作则使用4级共享更新排他锁。

2026-03-20 23:08:51 55

原创 openGauss之物化视图增量刷新代码走读

openGauss实现增量物化视图的核心机制是通过mlog表记录基表变更。当基表数据修改时,系统会将变更同步记录到对应的mlog表中。增量刷新时,通过ExecutorRefreshMatViewInc函数读取mlog表中的变更记录,将其应用到物化视图中。该实现方案简单直接,但存在一定限制,如不支持join操作。刷新完成后会清理已应用的mlog数据。整体实现通过维护变更日志表的方式,避免了全量刷新带来的性能开销。

2026-03-19 20:57:48 41

原创 openGauss 之 smp实现代码走读

本文分析了openGauss实现SMP(单机并行)功能的代码实现。首先在查询优化阶段生成并行执行计划,根据代价模型选择是否使用并行扫描;然后通过Stream算子汇聚并行计算结果。在执行阶段启动多个Stream Worker线程,各线程根据smp_id分配不同的数据块范围进行并行扫描。生产者线程将数据推送到共享队列,消费者线程通过Stream算子读取数据并返回给上层。这种设计避免了分布式执行计划转换,通过数据分区实现并行处理。

2026-03-18 22:54:02 244

原创 openGauss之 无用join消除

OpenGauss中的Join消除优化技术可以去除无实际意义的Left Join操作。当满足以下条件时可以进行Join消除:必须是Left Join、内表Join列具有唯一性约束、内表为单表且其列仅用于Join条件。子查询的Join消除还需额外判断其能否满足唯一性约束,如Distinct/Group By列包含Join条件列、使用聚合函数或UNION不含ALL等情况。该优化通过remove_useless_joins函数实现,会检查各种约束条件后从查询结构中移除无用内表。

2025-08-24 20:30:13 352

原创 openGauss之向量化执行引擎代码走读

这篇文章介绍了openGauss数据库中向量化执行引擎的实现原理,重点分析了sum聚合操作的向量化处理流程。文章首先说明了向量化执行引擎通过批量处理元组来提升性能的优势,随后按照执行流程详细解析了代码实现:从生成向量化执行计划、行存转列存、向量化聚合计算到最终结果转回行存输出。其中特别以sum聚合为例,展示了如何通过vinterval_sum函数进行批量计算。整个过程体现了openGauss如何通过数据存储格式转换和批量处理来实现高效的向量化计算能力,这对大数据量聚合查询的性能优化具有重要意义。

2025-06-29 18:17:28 436

原创 openGuass之子查询提升代码走读

openGuass中子查询提升(pull_up_sublinks)是指将xxx = exists (subquery),xxx = any(subquery)等子查询转换成Join查询,从而可以避免子查询被多次遍历导致的性能差的问题。

2025-04-25 23:17:24 437

原创 openGauss之推断隐式谓词条件代码走读

openGauss的隐式谓词推断是指通过SQL中明确的谓词条件推断出隐含的谓词条件,比如select * from test1 where b = 1 and a = b 可以直接推断出 a = 1的隐式谓词条件,并且将此谓词条件保存执行计划中,如下所示。正因为能推断出a = 1,所以才能使用a的索引条件加速。QUERY PLAN(3 rows)本文主要通过走读openGauss的代码了解openGauss中是如何根据现有的已知约束来推断出一些隐含约束的。

2025-03-30 14:05:56 456

原创 openGauss之排序算子实现的代码走读

​ 本文主要走读openGauss来了解openGauss中排序算子是如何实现的。

2025-01-02 23:39:50 524

原创 opengauss 之聚合算子实现代码走读

本文主要通过代码走读讲述openGauss中聚合算子的实现过程。在openGauss中,聚合分成两种,一个是简单聚合,比如对数据进行count等操作,另外一个是Hash聚合,先要对数据进行Hash分类,再对同类的数据进行聚合,如group by聚合。

2024-12-28 21:24:21 743

原创 openGauss之NestedLoop Join内表 Reuse

openGuass支持在做nestloop的时候,支持通过Materialize的方式将内表缓存到内存中,然后外表的数据内表数据进行碰撞的时候,如果内表已经缓存了数据,那么直接从缓存中直接读取内表的数据,从而实现内部数据Reuse。如下所示,不Reuse内表时内部的数据需要读三遍才能完成Join操作,但是内部数据Reuse时,只需要读取一遍即可。

2024-09-17 15:36:30 1370

原创 opeGauss 之BitmapOr算子代码走读

在openGauss中,BitmapOr算子扫描是指谓词条件是索引列的or条件时,将多个or条件的索引谓词先组成一个需要扫描元组的BitmapOr扫描算子,然后再通过BitmapOr算子的tid信息去扫描元组,从而减少or条件带来的随机扫描过多的问题,如下所示:本文主要通过走读代码了解openGauss是怎么实现BitmapOr算子的功能的。

2024-09-14 22:03:08 1364

原创 openGauss之TidScan

​ 在openGauss中,TidScan是指过滤谓词中包含ctid信息时,不再全表扫描然后通过eqal比对的方式进行计划,而是通过那到ctid谓词,直接通过tid获取到元组,然后再应用其他的过滤条件来过滤通过ticd获取到的元组。如下所示:本文主要讲述代码中是如何实现tidscan的。

2024-09-08 23:17:59 1374

原创 openGauss 之索引回表

​ 在openGauss中如果表有索引信息,查询的谓词条件中又包含索引列,openGauss支持通过索引信息快速拿到需要访问元组的位置信息,然后直接到该位置上取出元组数据,称之为回表查询。如下所示,利用索引索引列id=55快速找到t111上对应元组的位置信息,然后通过位置信息拿到id为55的元组中所有列的数据。本文通过走读openGauss的代码了解openGauss是怎样实现回表查询的。

2024-09-07 23:00:44 1405

原创 openGuass之CTE Reuse

​ CTE 是指with的公共表达式,如下所示是个CTE样例:​ CTE表达式往往在同一条sql中多次被重复引用,如上图所示的cte被引用了两次(c1 和 c2),我们称为2个CTE实例。​ 本文只要讲述在openGuass中,在sql中同一个CTE被多次引用时,数据是如何进行缓存和Reuse的。如上所示cte的c1和c2两个实例进行数据读取时,只要真正读取一次t11的表即可。

2024-09-01 16:40:03 1629 1

原创 openGauss 之谓词下推代码走读

谓词下推是每一个SQL引擎必备的功能。本文主要通过走读代码了解openGauss中是如何实现谓词下推能力的。谓词下推即是将过滤条件尽可能往tablescan的数据源节点下推,以实现上层算子尽可能少计算的能力,如下所示的执行计划便已经将谓词id

2024-08-26 00:30:21 1330

原创 openGauss之系统隐藏列

openGauss在建表时,系统会自动插入tableoid,cmax,xmax,cmin,xmin,ctid 六个系统隐藏列,在select*的时候也会自动隐藏这6个系统隐藏列,如下所示:本文主要走读代码了解openGauss是如何实现系统隐藏列的功能的。

2024-08-24 23:15:06 1461

原创 openGauss 之blks_hit统计实现的代码走读

​ 在openGauss中,select * from pg_stat_database可以看到每个数据库缓存命中率(blks_hit)的统计,如下所示:本文主要走读openGauss的代码来了解openGuass是在怎样进行缓存命中率的统计的。

2024-08-18 22:56:44 1916

原创 openGuass之shared_buffers代码走读

​ openGauss中的shared_buffers的配置项其实指的是共享缓冲区的大小,主要是用于配置缓冲数据块的大小。本文主要是通过走读代码了解在openGuass中shared_buffers的作用原理。

2024-07-08 23:36:07 1531 1

原创 openGauss 之min/max 优化代码走读

在openGuass中,如果对索引列执行max/min操作,openGauss会优化成只读取索引的最前/后的一行数据,避免了对整表数据进行读取和聚合操作,如下所示: 1. 首先需要将min/max 算子转成成执行计划中降序/升序的keypath,代码流程如下所示: 2. 生成索引路径的时候,根据keypath的信息生成顺序扫描路径还是逆序扫描路径,主要代码如下所示: 3. add_path的时候将带有pathkey的路径保存下来,主要代码流程如下所示:

2024-04-14 00:11:07 1477

原创 OpenGuass 之 where 1 = 0 处理流程代码走读

在OpenGuass中,如果where 条件中包含where 1= 0 等固定为否条件的查询语句,在生成执行计划的时候,执行计划是BaseResult类型,此类型的执行计划不会进行物理数据扫描,如下所示:对于非固定为否条件(如where id = 1)的语句,对应的执行计划则是SeqScan,此类计划会先执行物理扫描数据,扫描数据后在根据谓词条件进行优化,如下所示:本文主要是通过代码走读来了解在OpenGuass中对于where 1 = 0的固定为伪条件的处理流程。

2024-03-03 19:30:39 1337

原创 OpenGuass之分区裁剪

​ 本文将假设以一个以id为分区字段的表t1, 以SQL: select * from t1 where id > 2 and id < 5 为例讲述在OpenGuass中是如何进行分区裁剪的。如下图所示,本来t1有个6分区,但是OpenGuass会根据 id > 2 and id < 5的谓词条件进行无交集的分区裁剪,裁剪后实际扫描数据的时候,只会访问3个分区。

2024-01-30 23:11:34 1516

原创 OpenGauss 之PartitionMap

​ 本文主要是讲述OpenGuass中是如何将pg_partition系统表中的分区信息初始化成PartitionMap的。

2024-01-27 00:00:20 1522

原创 OpenGuass 之顺序扫描和索引扫描的代价估算

在OepnGuass中,一条路径的执行代价估算值将直接决定一条路径是否会被取舍。本文主要对OpenGuass中对于普通表的顺序扫描和索引扫描两种路径的的代价估算进行代码走读了解代价估算的整体过程。

2024-01-07 19:30:22 1503

原创 OpenGauss 之索引查找和匹配

本文主要通过走读OpenGuass的代码,来了解查询的时候OpenGuass是如何查找表的索引信息以及根据谓词条件过滤掉无用的索引信息的。

2024-01-01 15:16:53 1870

原创 Presto 之 Query & Stage的几种状态

当query被submit到resourceGroupManager后,query的状态变成WAITING_FOR_RESOURCES,WAITING_FOR_RESOURCES的状态主要为等待足够的worker个数,当worker的个数足够后,状态转为DISPATCHING状态。:QUEUED状态是query的初始状态,当CN收到查询的时候,会首先将该查询的状态置为QUEUED状态,QUEUED的查询会等待resource-group有可运行资源后进入到WAITING_FOR_RESOURCES阶段。

2023-09-16 23:55:35 1584

原创 Presto 之Pipeline

我们知道在Presto中有个叫Pipeline的概念,Pipeline其实就是一条包含各个算子的流水线,如下所示。本文主要介绍在Presto中,Pipeline是如何划分的。

2023-09-03 23:39:00 1523

原创 Presto之Driver个数

在Presto的Stage Performace中,每个Operator中都会有Driver个数的显示,如下图所示。本文主要介绍Presto中是如何决定Driver的个数的。

2023-08-27 20:52:22 1534

原创 Presto之Union算子的实现

在Presto中,Union的算子包括自动去重的Union操作和不去重的Union All操作。本文主要简述在Presto中Union All算子是如何实现和Union算子中是如何实现数据去重的。

2023-08-14 23:27:32 1753

原创 Presto RBO之ReorderJoins

在Presto中,ReorderJoins 的优化规则是指遍历Join表的各种顺序和类型的组合,在所有的组合中找到一个执行代价最小的执行计划来执行。ReorderJoins 是Join操作最重要的优化规则,本文主要介绍在Presto中,ReorderJoins 是如何实现的。

2023-07-24 00:17:08 1305

原创 Presto 之Semi Join的实现

在Presto中,select xxx from xxx where xxx in (select xxx from xx) 这种形式的SQL会被转成成Semi Join执行,通过xxx与子查询Join并且保留xxx的值实现in的过滤功能。本文主要介绍Semi Join在Presto中是如何实现的。

2023-07-19 23:50:09 1057

原创 Presto之内存池管理

在Presto 之GENERAL POOL & RESERVED POOL_王飞活的博客-优快云博客的文章中,我们介绍了在Presto中,内存分成了保留区和通用区两个内存池区进行管理。本文则主要介绍Presto是是如何实现内存池管理的。

2023-07-09 19:16:25 1288

原创 Presto 之GENERAL POOL & RESERVED POOL

我们知道,在Presto中,查询内存的分GENERAL内存池内存和RESERVED内存池内存。本文主要讲述在Presto中GENERAL POOL和RESERVED POOL的划分意义以及大小计算。

2023-07-05 00:35:34 1388

原创 Presto 之Cross Join消除的实现

Cross Join是指无条件的join。因为Cross Join的代价为笛卡尔乘积,代价很大,因此在Presto的执行优化中,会尽量消除掉Cross Join。Presto Cross Join的消除原理主要是尽可能通过对Join表的重新排序实现将Cross Join转换为Inner Join。本文主要讲述在Presto中是如何实现Cross Join消除的。

2023-06-25 23:44:19 1503

原创 Presto之 hash_partition_count

其实在Presto中,hash_partition_count的意义是限制一个Stage最多可以在多少个worker节点上运行,hash_partition_count超过Worker的总数量时此参数不起作用。hash_partition_count也不是对所有类型的Stage都可以生效,只有对可拆分成多个Task运行 的Stage才生效,比如Partition Join, Order by等算子,对于TableScan,TaskOutput等不可拆分运行的Stage,此参数不起作用。

2023-06-04 14:17:30 1635

原创 Presto之BroadCast Join的实现

在Presto中,Join的类型主要分成Partitioned Join和Broadcast Join,在Presto 之Hash Join的Partition_王飞活的博客-优快云博客中已经介绍了Presto的Partitioned Join的实现过程,本文主要介绍Broadcast Join的实现。

2023-05-27 23:10:04 2462

原创 Presto之 Exchange和访问MetaStore的反压机制

反压(backoff)是指网络请求如果失败时,将适当削弱访问的请求流量,避免造成更大拥塞。在Presto中,支持Exchange和MetaStore两种请求的自动反压,本文主要介绍在Presto中,这两种反压是如何实现的。

2023-05-24 00:23:25 1824

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除