我希望能够在Parquet桌上进行快速查询。与总大小相比,要返回的数据量非常小,但由于必须执行完整列扫描,因此对于我的用例来说太慢了。
使用索引可以解决这个问题,我读到这将在Parquet 2.0中添加。但是,我找不到任何其他信息,所以我猜它不是。如果对数据进行排序,我认为不存在阻止添加(多列)索引的任何基本障碍,在我的情况下是这样。
我的问题是:何时将索引添加到Parquet,以及这样做的高级设计是什么?我想我已经对指出正确分区的索引感到满意。
亲切的问候,
Sjoerd。
答案 0 :(得分:26)
Parquet目前保留每个数据页面的最小/最大统计数据。对于单个列,数据页是一组~1MB的值(在编码之后);多个页面组成了Parquet's column chunks。
这些最小/最大值用于过滤列块和构成块的页面。因此,您应该能够通过按要筛选的列对记录进行排序,然后将数据写入Parquet来改善查询时间。这样,您可以充分利用统计数据过滤。
您还可以通过减少页面和行组大小来使用此技术进行更精细的过滤,但您可以随后交换编码效率和I / O效率。
答案 1 :(得分:14)
更新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: **/
}
索引页面标题尚未实现。
请参阅上面的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