总体流程:根据用户给定的 Filter,先对文件中所有 RowGroup (Block) 过滤一遍,留下满足要求的 RowGroup。对这些 RowGroup 中涉及到的所有 Chunk 都读出来,对其中的 Page 一个一个解压缩,拼成一个一个 Record,再进行过滤。
细节:
- 不管一个 page 是否满足条件,都会被反序列化。
- 将多个 page 的东西拼成一个 record,并进行过滤,过滤结果放到 IncrementallyUpdatedFilterPredicate 谓词里,并根据这个结果选择是否返回这行数据。
读取流程
-
读取文件元数据
首先在 ParquetReader.build 时,读取文件尾部的 Footer,里边有整个文件的元数据,即ParquetMetadata。
-
初始化: ParquetReader.initReader()
- 过滤 RowGroup。根据 RowGroup 中的统计信息和 Filter,对文件中的所有 RowGroup 进行过滤,将不满足的 RowGroup 丢掉。
-
构造 RecordReader: InternalParquetRecordReader.checkRead()
- 读取一个 RowGroup (包含各个 Chunk 的 PageReader),将查询涉及的所有 Chunk 的字节读到内存中。
- 对每个 Chunk,将其所有 Page 构造出来,用字节数组填充,作为压缩后的 Page,并用这些压缩的 Page 和解码器构造一个 ColumnChunkPageReader。
- 根据这些 Col