⌘+k ctrl+k
1.4 (LTS)
搜索快捷键 cmd + k | ctrl + k
执行格式

Vector(向量)是用于在执行期间存储内存数据的容器格式。DataChunk 是向量的集合,例如用于表示 PhysicalProjection 算子中的列列表。

数据流

DuckDB 使用向量化查询执行模型。DuckDB 中的所有算子都经过优化,以处理固定大小的向量。

这种固定大小在代码中通常被称为 STANDARD_VECTOR_SIZE。默认的 STANDARD_VECTOR_SIZE 为 2048 个元组。

向量格式

向量在逻辑上表示包含单一类型数据的一维数组。DuckDB 支持不同的向量格式,这允许系统以不同的物理表示来存储相同的逻辑数据。这可以实现更紧凑的表示,并有可能在整个系统中实现压缩执行。以下是所支持向量格式的列表。

扁平向量 (Flat Vectors)

扁平向量在物理上存储为连续数组,这是标准的未压缩向量格式。对于扁平向量,其逻辑表示和物理表示是相同的。

Flat Vector example

常量向量 (Constant Vectors)

常量向量在物理上存储为单个常量值。

Constant Vector example

当数据元素重复时,常量向量非常有用——例如,在表示函数调用中常量表达式的结果时,常量向量允许我们只存储该值一次。

SELECT lst || 'duckdb'
FROM range(1000) tbl(lst);

由于 duckdb 是一个字符串字面量,因此每一行的字面量值都是相同的。在扁平向量中,我们必须为每一行重复存储一次 'duckdb'。而常量向量允许我们只存储该字面量一次。

常量向量也由存储引擎在进行常量解压缩时发出。

字典向量 (Dictionary Vectors)

字典向量在物理上存储为一个子向量,以及一个包含指向该子向量索引的选择向量。

Dictionary Vector example

字典向量由存储引擎在进行字典解压缩时发出。

正如常量向量一样,字典向量也由存储引擎发出。在反序列化字典压缩的列段时,我们会将其存储在字典向量中,以便在查询执行期间保持数据压缩状态。

序列向量 (Sequence Vectors)

序列向量在物理上存储为一个偏移量和一个增量值。

Sequence Vector example

序列向量对于高效存储增量序列非常有用。它们通常用于行标识符。

统一向量格式 (Unified Vector Format)

不同向量格式的这些属性对于优化目的非常有用。例如,你可以想象这样一种场景:函数的所有参数都是常量,我们只需计算一次结果并发出一个常量向量即可。但由于组合爆炸的可能性,为每个函数的每种向量类型组合编写专用代码是不可行的。

为了解决这个问题,当你想要不分类型地通用化使用向量时,可以使用 UnifiedVectorFormat。该格式本质上充当了 Vector 内容的通用视图。每种类型的 Vector 都可以转换为这种格式。

复杂类型

字符串向量 (String Vectors)

为了高效存储字符串,我们使用了 string_t 类。

struct string_t {
    union {
        struct {
            uint32_t length;
            char prefix[4];
            char *ptr;
        } pointer;
        struct {
            uint32_t length;
            char inlined[12];
        } inlined;
    } value;
};

短字符串(<= 12 字节)被内联到结构中,而较长的字符串则存储一个指向辅助字符串缓冲区数据的指针。长度信息在整个函数中被使用,以避免调用 strlen 并持续检查空指针。前缀用于比较时的快速失败(当通过前缀判断不匹配时,我们知道字符串不相等,因此无需进一步寻找指针)。

列表向量 (List Vectors)

列表向量存储为一系列列表条目以及一个子向量。子向量包含列表中实际存在的,而列表条目则指定了每个独立的列表是如何构建的。

struct list_entry_t {
    idx_t offset;
    idx_t length;
};

偏移量 (Offset) 指向子向量中的起始行,长度 (Length) 用于跟踪该行列表的大小。

列表向量可以递归存储。对于嵌套列表向量,列表向量的子向量依然是一个列表向量。

例如,考虑这个类型为 BIGINT[][] 的向量的模拟表示。

{
   "type": "list",
   "data": "list_entry_t",
   "child": {
      "type": "list",
      "data": "list_entry_t",
      "child": {
         "type": "bigint",
         "data": "int64_t"
      }
   }
}

结构体向量 (Struct Vectors)

结构体向量存储一个子向量列表。子向量的数量和类型由结构体的 schema(模式)定义。

映射向量 (Map Vectors)

在内部,映射向量存储为 LIST[STRUCT(key KEY_TYPE, value VALUE_TYPE)]

联合向量 (Union Vectors)

在内部,UNION 使用与 STRUCT 相同的结构。第一个“子项”总是被 UNION 的标签向量(Tag Vector)占据,它记录了每一行对应于 UNION 类型中的哪一种。

© 2025 DuckDB 基金会,阿姆斯特丹,荷兰
行为准则 商标使用指南