Apache Iceberg 中引入索引提升查询性能( 三 )

索引文件格式采用[puffin]https://iceberg.apache.org/puffin-spec/格式 , 这是一种二进制格式 。Magic Blob? Blob? ... Blob? Footer
在 Footer 中保存每个 blob 的元数据信息 。索引构建成功后 , 会生成类似于下面内容的文件 。
 

Apache Iceberg 中引入索引提升查询性能

文章插图
 
索引带来的收益Range-Encoded BitMap 适用于多维分析场景 , 且 Ranger 范围较小时 , 效果非常明显 。下面我们基于 Spark 引擎性能测试 。
  1. 构造 1TB 的 SSB 测试数据 , 分别在构建 Index 前后 , 对以下用例进行测试 。
Q1: SELECT count(*) FROM lineorder WHERElo_ordtotalprice = 19665277Q2: SELECT count(*) FROM lineorder WHERElo_ordtotalprice = 19665277 AND lo_revenue= 2141624Q3: SELECT count(*) FROM lineorder WHERElo_ordtotalprice = 19665277 AND lo_revenue>=10304000Q4: SELECT count(*) FROM lineorder WHERElo_ordtotalprice = 21877827 AND lo_revenue>= 83800AND lo_revenue<= 103800Q5: SELECT count(*) FROM lineorder WHERElo_ordtotalprice > 21877827 AND lo_revenue>= 83800AND lo_revenue<= 93800Q6: SELECT count(*) FROM lineorder WHERE lo_ordtotalprice >= 93565 ANDlo_ordtotalprice < 93909Q7: SELECT count(*) FROM lineorder WHERElo_ordtotalprice >= 93565 ANDlo_ordtotalprice < 91003562 AND lo_revenue>=904300 AND lo_revenue<= 9904300 
Apache Iceberg 中引入索引提升查询性能

文章插图
 
左图展示了 7 条 SQL 语句分别在没有 Index 和采用 Index 情况下的执行时间 。右图展示采用 Index 后 , 7 条 SQL 语句读数据的 split 数量 。很明显读数据的 split 数量越少 , Index 效果越好 。最糟糕的情况 , 所有的 split 都参数计算 , 这时和没有构建索引的效果类似 。
  1. 采用 SSB 基准测试
由于 SSB 提供的测试场景 , 和 Range-Encoded 有利的场景 , 不太匹配 , 所以 Index 的效果并没有明显的效果 。但也不会比不采用 Index 的效果差 。如下面左图 , 分别是构建索引前后 , SQL 语句的执行时间 , 构建索引的优势并没有体现出来 。右图中 , 可以看到所有的 split 都参与了计算 。
 
Apache Iceberg 中引入索引提升查询性能

文章插图
 
总结根据上面的介绍 , 这里总结下 Iceberg 中索引实现的一些特征:
  • 细粒度索引级别:提供 RowGroup/Stripe 级别的索引 , 可以更加精确的定位数据的查询范围 , 减少不必要数据输入 , 从而提高查询性能;
  • 索引作用于执行端:查询任务被分配多个执行端 , 每个执行端只判断该节点上的 RowGroup/Stripe 数据是否符合即可;
  • 适配多种引擎:索引构建后 , 可用于多种引擎;
  • 提供异步构建 Index , 从而不影响主业务的进行;
  • 适用于高基数 & 低基数场景 , 且占有存储空间小 。满足范围查询、等值查询等场景 。且范围越小 , 收益效果越明显 。




推荐阅读