Paimon的索引

7 阅读6分钟

(14) 文件索引和查询性能

对于 Merge On Read 表,您应该注意的最重要的事情是存储桶的数量,这将限制 读取数据的并发性。

对于 MOW(删除向量)或 COW 表或读取优化表, 读取数据的并发性没有限制,他们也可以对非主键列使用一些过滤条件。

<1> 通过主键过滤进行数据跳过

对于常规的分桶表(例如,bucket = 5),主键的过滤条件可以大大加速查询并减少大量文件的读取。

<2> 通过文件索引进行数据跳过

支持的过滤类型包括:

  • Bloom Filter:指定需要Bloom Filter索引的列。
  • Bitmap:指定需要Bitmap索引的列。
  • Bit-Slice Index Bitmap:指定需要BSI索引的列。

您可以在启用 Deletion Vectors 的情况下使用 file index to table,它在读取端按索引筛选文件。

CREATE TABLE <PAIMON_TABLE> WITH (
    'deletion-vectors' = 'true',
    'file-index.bloom-filter.columns' = 'c1,c2',
    'file-index.bloom-filter.c1.items' = '200'
);

支持的筛选条件类型:

Bloom Filter:

  • file-index.bloom-filter.columns:指定需要 Bloom Filter 索引的列。
  • file-index.bloom-filter.<column_name>.fpp配置误报概率。
  • file-index.bloom-filter.<column_name>.items在一个数据文件中配置预期的 distinct 项。

Bitmap:

  • file-index.bitmap.columns:指定需要 Bitmap 索引的列。
Bit-Slice Index Bitmap`
  • file-index.bsi.columns:指定需要 BSI 索引的列。

将支持更多过滤器类型…

如果要向现有表添加文件索引,而无需任何重写,则可以使用 procedure。以前 我们使用 Procedure, you should configure appropriate configurations in Target Table.您可以使用 ALTER 子句对表进行配置。rewrite_file_index``file-index.<filter-type>.columns

对于每个文件,Paimon 都会为其创建相应的索引文件。如果索引文件过小,它将直接存储在清单中,或者存储在数据文件所在的目录中。每个数据文件都对应一个索引文件,该索引文件有独立的文件定义,并且可以包含不同类型的、涉及多列的索引。

file-index.${index_type}.columns:文件索引.${索引类型}. 列

《1》File

文件索引文件格式。将所有 line 和 offset 放在 header 中。

 _____________________________________    _____________________
|     magic    |version|head length |
|-------------------------------------|column number            |
|-------------------------------------|column 1        | index number   |
|-------------------------------------|
|  index name 1start pos |length  |
|-------------------------------------|
|  index name 2start pos |length  |
|-------------------------------------|
|  index name 3start pos |length  |
|-------------------------------------|            HEADcolumn 2        | index number   |
|-------------------------------------|
|  index name 1start pos |length  |
|-------------------------------------|
|  index name 2start pos |length  |
|-------------------------------------|
|  index name 3start pos |length  |
|-------------------------------------|
|                 ...                 |
|-------------------------------------|
|                 ...                 |
|-------------------------------------|
|  redundant length |redundant bytes |
|-------------------------------------|    ---------------------
|                BODY                 |
|                BODY                 |
|                BODY                 |             BODY
|                BODY                 |
|_____________________________________|    _____________________
*
magic:                            8 bytes long, value is 1493475289347502L, BIT_ENDIAN
version:                          4 bytes int, BIT_ENDIAN
head length:                      4 bytes int, BIT_ENDIAN
column number:                    4 bytes int, BIT_ENDIAN
column x name:                    2 bytes short BIT_ENDIAN and Java modified-utf-8
index number:                     4 bytes int (how many column items below), BIT_ENDIAN
index name x:                     2 bytes short BIT_ENDIAN and Java modified-utf-8
start pos:                        4 bytes int, BIT_ENDIAN
length:                           4 bytes int, BIT_ENDIAN
redundant length:                 4 bytes int (for compatibility with later versions, in this version, content is zero)
redundant bytes:                  var bytes (for compatibility with later version, in this version, is empty)
BODY:                             column index bytes + column index bytes + column index bytes + .......

《2》BloomFilter

定义。'file-index.bloom-filter.columns'

bloom filter index 的内容很简单:

  • numHashFunctions 4 字节 int, BIT_ENDIAN

  • 布隆过滤器字节数

此类使用 (64 位) 长哈希。仅存储 num 哈希函数 (一个整数) 和位集字节。哈希字节类型 (如 varchar、binary 等)使用 xx 哈希,哈希数字类型由指定的数字哈希

特点:牺牲一定精度,实现高效数据检索和去重

应用场景:去重、索引

《3》Bitmap

定义。'file-index.bitmap.columns'

位图文件索引格式 (V1):

1版本(version):占 1 字节。
2行数(row count):为 4 字节的整数,用于表示相关数据的行数。
3非空值位图数量(non - null value bitmap number):4 字节整数,记录非空值位图的数量。
4是否有空值(has null value):占 1 字节,用于标识数据中是否存在空值。
5空值偏移(null value offset):若存在空值,该字段为 4 字节,用于记录空值的偏移量。
6值与偏移对(value x | offset x):由可变长度字节的value(作为位图标识符,可为任意数据类型)和 4 字节整数的offset组成,offset为负时,表示只有一个值,其位置为该负值的相反数。
7序列化位图(serialized bitmap):属于主体部分,由多个序列化位图组成,用于实际存储位图索引信息,可根据非空值位图数量等信息来确定其数量和内容。

Bitmap file index format (V1)
+-------------------------------------------------+-----------------
| version (1 byte)                               |
+-------------------------------------------------+row count (4 bytes int)                        |
+-------------------------------------------------+
| non-null value bitmap number (4 bytes int)     |
+-------------------------------------------------+
| has null value (1 byte)                        |
+-------------------------------------------------+null value offset (4 bytes if has null value)  |       HEAD
+-------------------------------------------------+value 1 | offset 1+-------------------------------------------------+value 2 | offset 2+-------------------------------------------------+value 3 | offset 3+-------------------------------------------------+
| ...                                            |
+-------------------------------------------------+-----------------
| serialized bitmap 1+-------------------------------------------------+
| serialized bitmap 2+-------------------------------------------------+       BODY
| serialized bitmap 3+-------------------------------------------------+
| ...                                            |
+-------------------------------------------------+-----------------
*
value x:                       var bytes for any data type (as bitmap identifier)
offset:                        4 bytes int (when it is negative, it represents that there is only one value
                                 and its position is the inverse of the negative value)

特点:牺牲一定存储空间,实现高效集合操作和位运算

应用场景:集合操作、位运算、索引

《4》Bit-Slice Index Bitmap 位片索引位图

概念1:数据分片

将数值按二进制或十进制位分解为多个"位片"(例如数值18的二进制为10010,可分解为第0位到第4位的5个切片)。每个切片对应一个独立的位图,记录该位是否为1。例如,价格字段的数值分解后,每个位图表示该位是否满足特定条件(如最高位是否为1)。

概念2:范围编码

与传统位图的等值编码不同,BSI采用范围编码:每个位图不再表示"等于某值",而是表示"大于等于某值"。例如,位图可能表示"第3位>=1",从而覆盖多个数值范围

概念3:索引结构

BSI索引文件存储每个位片的元数据(如最小值、最大值)和对应的位图。查询时通过位运算组合多个切片,快速定位满足条件的行

BSI 文件索引是一个数值范围索引,用于加速范围查询,可以与 bitmap 索引一起使用。

定义。'file-index.bsi.columns'

BSI 文件索引格式 (V1):相当于位图的二级索引,可以加速查询,优化聚合操作。

BSI 可以先过滤出相关数据,再进行聚合,提高聚合效率。

特点:存储空间小(高基数列)、支持between、>、<等范围查询、计算聚合值时,可直接基于分片位图统计每位的权重;对于parquet格式,BSI索引可下推到Page粒度(数据存储的最小单元),结合列存特性进一步减少I/O

使用:

ALTER TABLE my_table SET ('file-index.bsi.columns' = 'price, timestamp');
使用bitmap和bit slice index bitmap

-- Step 1: 建表
CREATE TABLE sales (
    id INT PRIMARY KEY NOT ENFORCED,
    product_id STRING,
    gender STRING,
    status STRING,
    price BIGINT,
    timestamp BIGINT,
    region STRING
) WITH (
    'connector' = 'paimon',
    'path' = 'hdfs://path/to/paimon/sales',
    'file.format' = 'parquet'
);

-- Step 2: 配置索引
ALTER TABLE sales SET (
    'file-index.bitmap.columns' = 'gender, status',
    'file-index.bsi.columns' = 'price, timestamp'
);
-- Step 3: 初始化索引(若表已有数据)
CALL sys.rewrite_file_index('sales');

或者可以建表的时候直接创建
-- 在 CREATE TABLE 时直接定义位图和位片索引
CREATE TABLE sales (
    id INT PRIMARY KEY NOT ENFORCED,
    product_id STRING,
    gender STRING,
    status STRING,
    price BIGINT,
    timestamp BIGINT,
    region STRING
) WITH (
    'connector' = 'paimon',
    'path' = 'hdfs://path/to/paimon/sales',
    'file.format' = 'parquet',
    'file-index.bitmap.columns' = 'gender, status',  -- 位图索引
    'file-index.bsi.columns' = 'price, timestamp'     -- 位片索引
);

-- 若表已有数据,初始化索引
CALL sys.rewrite_file_index('sales');
BSI file index format (V1)
+-------------------------------------------------+
| version (1 byte)                               |
+-------------------------------------------------+row count (4 bytes int)                        |
+-------------------------------------------------+
| has positive value (1 byte)                    |
+-------------------------------------------------+
| positive BSI serialized (if has positive value)|       
+-------------------------------------------------+
| has negative value (1 byte)                    |
+-------------------------------------------------+
| negative BSI serialized (if has negative value)|       
+-------------------------------------------------+

BSI 序列化格式 (V1):

BSI serialized format (V1)
+-------------------------------------------------+
| version (1 byte)                               |
+-------------------------------------------------+
| min value (8 bytes long)                       |
+-------------------------------------------------+
| max value (8 bytes long)                       |
+-------------------------------------------------+
| serialized existence bitmap                    |       
+-------------------------------------------------+
| bit slice bitmap count (4 bytes int)           |
+-------------------------------------------------+
| serialized bit 0 bitmap                        |
+-------------------------------------------------+
| serialized bit 1 bitmap                        |
+-------------------------------------------------+
| serialized bit 2 bitmap                        |
+-------------------------------------------------+
| ...                                            |
+-------------------------------------------------+

BSI支持的数据类型:文件索引 |Apache 派蒙