🗒️Parquet(3)谓词下推
2023-7-31
| 2023-8-21
0  |  阅读时长 0 分钟
type
status
date
slug
summary
tags
category
icon
password

背景

在 SQL 查询中,有两个重要的优化,就是谓词映射和谓词下推。
  • 谓词映射
获取表中原始数据时只需要扫描查询中需要的列,所以分区取出每一列的所有值就可以实现对查询数据的扫描,而避免扫描整个表文件内容。
例如对一个包含了 id、name 字段的表 test_table,考虑下面的 SQL:
如果可以的话,我们只需要取出 id 的所有数据就可以了,不需要考虑 name 字段的数据。
Parquet 格式采用列存储,原生支持谓词映射,我们只需要找到所有 rowgroup 中对应的几个 column chunk 进行读取就可以了,其他不涉及到的列对应的 column chunk 完全不需要考虑。
  • 谓词下推
将一些过滤条件尽可能的在靠近数据源的地方执行以减少每一层交互的数据量。
在前面的例子中,有一个过滤条件 id < 100,我们当然可以把全部 id 数据都读取出来然后在内存进行过滤,不过如果可以在从文件中读取数据的时候就无视掉不满足条件的数据,那我们就省去了在 SQL 执行的过程中进行处理了。
Parquet 的元数据可以帮助实现谓词下推在数据源的过滤,从而加快查询。

元数据

Parquet 总共有 3 中类型的元数据:文件元数据、列(块)元数据和 page header 元数据。
如下图所示:
notion image
实际上我们需要关心的只有 columnmetadata 这一元数据,它包含了每一列的统计信息。
columnmetadata 在 file 和 columnchunk 级别都存在,这意味着我们可以使用它去在这两个级别进行过滤:在 file 级别进行过滤,我们可以忽略这个文件;在 columnchunk 级别进行过滤,我们可以忽略这个 columnchunk。
不过上面的图片有些落后,这里取出 columnchunk 完整的定义:
可以看到,columnmetadata 包含了类型(type)、编码方式(encodings)、压缩算法名(codec)、统计数据(statistics、布隆过滤器的偏移量(bloom_filter_offset)等。
其中 statistics 和 bloom_filter_offset 可以用于过滤数据。
  • statistics
Parquet 里列的统计数据包括该列的最大值(max),最小值(min)和空数据数量(num_nulls)。
统计数据可以用于 SQL 中的范围查询和等值查询。例如下面这个查询:
我们取出 Parquet 文件中的 statistics 信息,如下:
根据这个统计信息,我们可以判断出 file2 是不需要读取的。
  • bloom_filter_offset
bloom_filter_offset 用于构建布隆过滤器,布隆过滤器可以用于判断某些数据一定不存在于这个文件,因此可以用在 SQL 中的等值查询(点查询)的过滤。例如下面这个查询:
我们使用布隆过滤器可以判断某个值一定不在某个文件,可能在某个文件,比如前面的两个文件,判断结果如下:
因此我们可以过滤掉 file1.rowgroup1.columnchunk2 和 file2,减少读取工作量。

总结

Parquet 实际上提供了 file 和 columnchunk 级别的数据过滤,包含了 statistics 和 bloom_filter 两种过滤方法,分别适用于范围查询和点查询。
  • Parquet
  • Parquet(2)striping and assembly 算法zorder 空间曲线
    Loading...
    目录