SPARK Parquet嵌套类型的向量化支持以及列索引(column index)

简介: SPARK Parquet嵌套类型的向量化支持以及列索引(column index)

背景

本文基于Spark 3.3.0

列式存储Parquet文件越来越受到工业界的青睐,在delta以及Spark中应用广泛,具体的项目见:parquet-mr


分析

Parquet格式

关于parquet的格式存储以及读取,可以参考大数据列存标准格式 - Parquet,总结一下就是:

Parquet采用类似Protobuf的协议来描述数据的Schema,字段的描述有三种(逻辑上):


required  有且仅有一次
optional 0或1次
repeated 0次或多次

具体到物理存储,就得有Repetition Level(对应repeated),Definition Level(对应optional) ,required是不需要的,因为字段存在就有,不存在就没有。

其实这种很好理解,因为在Dremel/Parquet中,提出的是以树状形式来组织schema中的字段,举例子:

message AddressBook {
  required string owner;
  repeated string phoneNumber;
  repeated group contacts {
    required string name;
    optional string phoneNumber;
  }
}


对应到树形结构为


              AddressBook
          /           |               \  
         V            V                V
       owner      phoneNumber    contacts
                                    /    \
                                   V      V
                                 name    phoneNumber 

这样用Repetition Level 和Definition Level来表示数据位于哪一层级就能精确定位一个数据。


Parquet嵌套类型向量化


根据以上的Parquet的格式存储,在读取的Parquet文件的时候,对于非向量化的读取,是一行一行的读取,支持所有类型,对于向量化的读取在Spark 3.3.0以前是不支持嵌套类型(如 struct map list)的。

具体行读取如下(具体到page级别):


f0a4253f34814d1c97a4f65ee3fc9d1d.png



47c25e6fbcf742a99d80c1f3f4639102.png


可以看到是按照批次读取的。

注意:按照schema的定义,有些数据有可能是不存在的,所以对于同一列对应的Repetition Level 和Definition Level也有可能是不一样的。

性能也是有很大的提升:


77eec39f50b4409c8cc92688ee7f3779.png


Parquet的列索引

在Parquet 1.11.0之前,Parquet是不支持列索引的,具体见PARQUET-1201

在Spark 3.2.0 便支持了paruqet的列索引的读取,具体见:SPARK-26345

在spark 3.2.0 之前Parquet的谓词下推是基于Row group的统计信息来的,如:最大最小值,字典信息,以及Parquet-1.12的Bloom filter,

在Spark 3.2.0 之后,我们可以基于page级别的数据过滤(只选择需要的page),这样能大大减少IO,因为在page级别过滤的话,不需要每次都会获取整个Row group的数据。


81f148fa8fc14e399e2c631e4297cac2.png

具体的实现逻辑如下:


42feaa67cf484cc0a4f20451c111a1a5.png


之前的读取是把对应Row group的数据全部读取过来,之后再进行过滤。

相关文章
|
关系型数据库 PostgreSQL
PostgreSQL listagg within group (order by) 聚合兼容用法 string_agg ( order by) - 行列变换,CSV构造...
标签 PostgreSQL , order-set agg , listagg , string_agg , order 背景 listagg — Rows to Delimited Strings The listagg function transforms values from a g...
6251 0
|
OLAP Serverless
openGauss向量化引擎--hash join
openGauss向量化引擎--hash join
138 0
|
SQL 分布式计算 HIVE
spark sql编程之实现合并Parquet格式的DataFrame的schema
spark sql编程之实现合并Parquet格式的DataFrame的schema
350 0
spark sql编程之实现合并Parquet格式的DataFrame的schema
|
存储 分布式计算 大数据
SPARK Parquet嵌套类型的向量化支持以及列索引(column index)
SPARK Parquet嵌套类型的向量化支持以及列索引(column index)
556 0
SPARK Parquet嵌套类型的向量化支持以及列索引(column index)
|
SQL HIVE
hive插入分区报错SemanticException Partition spec contains non-partition columns
hive插入分区报错SemanticException Partition spec contains non-partition columns
|
消息中间件 传感器 分布式计算
【Spark】Spark Dataframe 对项目中的数据实现列转行操作
【Spark】Spark Dataframe 对项目中的数据实现列转行操作
531 0
【Spark】Spark Dataframe 对项目中的数据实现列转行操作
|
SQL 分布式计算 Spark
spark CTAS union all (union all的个数很多)导致超过spark.driver.maxResultSize配置(1G)
spark CTAS union all (union all的个数很多)导致超过spark.driver.maxResultSize配置(1G)
892 0
|
存储 缓存 Apache
Apache doris 排序键及ShortKey Index
Apache Doris中为加速查询,在内部组织并存储数据时,会把表中数据按照指定的列进行排序,这部分用于排序的列(可以是一个或多个列),可以称之为Sort Key。明细模型中Sort Key就是指定的用于排序的列(即 DUPLICATE KEY 指定的列),聚合模型中Sort Key列就是用于聚合的列(即 AGGREGATE KEY 指定的列),唯一主键模型中Sort Key就是指定的满足唯一性约束的列(即 UNIQUE KEY 指定的列)。
1396 0
|
弹性计算 关系型数据库 测试技术
PostgreSQL 分区表如何支持多列唯一约束 - 枚举、hash哈希 分区, 多列唯一, insert into on conflict, update, upsert, merge insert
标签 PostgreSQL , 分区表 , native partition , 唯一 , 非分区键唯一 , 组合唯一 , insert into on conflict , upsert , merge insert 背景 PG 11开始支持HASH分区,10的分区如果要支持hash分区,可以通过枚举绕道实现。 《PostgreSQL 9.x, 10, 11 hash分区表 用法举例
3143 0
|
存储 对象存储 开发者
DLA支持Parquet/ORC/OTS表的Alter Table Add Column
蛮多客户提过需求:要给一个表添加列,之前推荐的做法是让客户把表删掉重建,因为DLA是计算存储分离的,删掉的其实只是计算层的元数据,存储层的数据不会动,还是比较轻量级的一个操作。不过这种做法对于一些有特别多分区的表来说代价还是还是挺大的,要删掉所有的分区,而且可能会影响其它正在使用这个表的任务,为了解决用户的这个痛点,我们现在对部分数据源(Parquet/Orc)进行了的Alter Table Add Column的支持。
1878 0
DLA支持Parquet/ORC/OTS表的Alter Table Add Column