apache / apache/arrow-rs

[EPIC] Faster performance for parquet predicate evaluation for non selective filters

Open
#7,456 22 comments 2 reactions 1 assignee Claimed by @alamb View on GitHub
enhancement parquet
Dominant language
Rust
Stars
3.6k
Forks
1.3k
Avg merge
2d 18h
Merged PRs (30d)
169

Description

## Is your feature request related to a problem or challenge? Please describe what you are trying to do.

- Related to https://github.com/apache/datafusion/issues/3463 in DataFusion.

When evaluating filters on data stored in parquet, you can:
1. Use the [`with_row_filter`] API to apply predicates during the scan
2. Read the data and apply the predicate using the [`filter`] kernel afterwards

Currently, it is faster to use [`with_row_filter`] for some predicates and [`filter`] for others. In DataFusion we have a configuration setting to choose between the strategies (`filter_pushdown`, see https://github.com/apache/datafusion/issues/3463) but that is a bad UX as it
means the user must somehow know which strategy to choose, but the strategy changes

In general the queries that are slower when [`with_row_filter`] is used:
1. The predicates are not very selective (e.g. they pass more than 1% of the rows)
2. The filters are applied to columns which are also used in the query result (e.g. the a filter column is also in the projection)

### More Background:

The predicates are provides as a [`RowFilter`] (see docs for more details)

> [RowFilter](https://docs.rs/parquet/latest/parquet/arrow/arrow_reader/struct.RowFilter.html) applies predicates in order, after decoding only the columns required. As predicates eliminate rows, fewer rows from subsequent columns may be required, thus potentially reducing IO and decode.

[`with_row_filter`]: https://docs.rs/parquet/latest/parquet/arrow/arrow_reader/struct.ArrowReaderBuilder.html#method.with_row_filter
[`filter`]: https://docs.rs/arrow/latest/arrow/compute/kernels/filter/index.html
[`RowFilter`]: https://docs.rs/parquet/latest/parquet/arrow/arrow_reader/struct.RowFilter.html

## Describe the solution you'd like

I would like the evaluation of predicates in `RowFilter` (aka pushed down predicates) to never be worse than decoding the columns first and then filtering them with the `filter` kernel

We have added a benchmark https://github.com/apache/arrow-rs/pull/7401, which hopefully can

```shell
cargo bench --all-features --bench arrow_reader_row_filter
```

**Describe alternatives you've considered**
This goal will likely require several changes to the codebase. Here are some options:
- [x] https://github.com/apache/arrow-rs/pull/7401
- [x] https://github.com/apache/arrow-rs/issues/7460
- [x] https://github.com/apache/arrow-rs/issues/7589
- [x] https://github.com/apache/arrow-rs/issues/7363
- [x] https://github.com/apache/arrow-rs/issues/5523
- [ ] https://github.com/apache/arrow-rs/issues/7450
- [ ] https://github.com/apache/arrow-rs/issues/7458
- [ ] https://github.com/apache/arrow-rs/issues/4864
- [x] https://github.com/apache/arrow-rs/issues/8565
- [x] https://github.com/apache/arrow-rs/issues/8844
- [x] https://github.com/apache/arrow-rs/issues/8845
- [ ] https://github.com/apache/arrow-rs/issues/8846
- [x] https://github.com/apache/arrow-rs/issues/8847

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.