小智 31
Parquet目前保留每个数据页面的最小/最大统计数据.对于单个列,数据页是一组~1MB的值(在编码之后); 多个页面构成了Parquet的列块.
这些最小/最大值用于过滤列块和构成块的页面.因此,您应该能够通过按要筛选的列对记录进行排序,然后将数据写入Parquet来改善查询时间.这样,您可以充分利用统计信息过滤功能.
您还可以通过减少页面和行组大小来使用此技术进行更精细的过滤,尽管您可以交换编码效率和I/O效率.
Tag*_*gar 21
更新Dec/2018:
Parquet Format版本2.5添加了列索引.
https://github.com/apache/parquet-format/blob/master/CHANGES.md#version-250
有关该新功能的子任务列表,请参阅https://issues.apache.org/jira/browse/PARQUET-1201.
请注意,此功能本身已合并为Parquet格式,不同的后端(Spark,Hive,Impala等)需要一些时间才能开始支持它.
此新功能称为列索引.基本上Parquet在镶木地板布局中添加了两个新结构 - 列索引和偏移索引.
下面是一个更详细的技术说明,它解决了什么以及如何解决.
问题陈述
在当前格式中,为ColumnChunks中的ColumnChunks和DataPageHeader结构中的各个页面存储统计信息.在阅读页面时,读者必须处理页眉以确定是否可以基于统计数据跳过页面.这意味着读者必须访问列中的所有页面,因此可能从磁盘读取大部分列数据.
目标
通过允许基于最小值和最大值直接访问页面,使范围扫描和点查找I/O高效.特别是:
非目标
支持等价的二级索引,即对非键入数据的键值进行排序的索引结构.
技术方法
我们在行组元数据中添加了两个新的每列结构:ColumnIndex:这允许基于列值导航到列的页面,并用于定位包含扫描谓词的匹配值的数据页OffsetIndex:这允许导航行索引,用于通过ColumnIndex检索标识为匹配的行的值.一旦跳过列的行,就必须跳过其他列中的相应行.因此,RowGroup中每列的OffsetIndex都存储在一起.
新的索引结构与页脚附近的RowGroup分开存储,因此如果读取器没有进行选择性扫描,则读取器不需要支付I/O和反序列化成本来读取它们.索引结构的位置和长度存储在ColumnChunk和RowGroup中.
Cloudera的Impala团队已对这一新功能进行了一些测试(尚未作为Apache Impala核心产品的一部分提供).这是他们的性能改进:
和
正如您所看到的,一些查询在cpu时间和必须从磁盘读取的数据量方面都有了巨大的改进.
2016年的原始答案:
struct IndexPageHeader {
/** TODO: **/
}
Run Code Online (Sandbox Code Playgroud)
尚未实现索引页面标题.
请参阅上面的Parquet格式的源代码.我目前在Parquet 2.0中也没有看到它.
但是 - 来自Ryan Blue上面在Parquet上的优秀答案,它具有伪索引功能(布隆过滤器).
如果您对更多详细信息感兴趣,我建议使用有关Parquet绽放过滤器和谓词推送工作的精彩文档 https://www.slideshare.net/RyanBlue3/parquet-performance-tuning-the-missing-guide 更多技术特定于实现的文档 - https://homepages.cwi.nl/~boncz/msc/2018-BoudewijnBraams.pdf