apache / apache/datafusion

Investigate unexpected performance issue when adding a filter to reduce rows going into a join

Open
#2,742 2 comments 0 reactions 0 assignees View on GitHub
enhancement
Dominant language
Rust
Stars
9.3k
Forks
2.4k
Avg merge
3d 7h
Merged PRs (30d)
344

Description

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

I have a query that performs a join and the join key contains null values on one side. If I run a plain join I see this performance:

```
$ time bdt query --sql "select count(*) from web_sales join customer on web_sales.ws_bill_customer_sk = customer.c_customer_sk" --table customer.parquet --table web_sales.parquet
+-----------------+
| COUNT(UInt8(1)) |
+-----------------+
| 71983355 |
+-----------------+

real 0m0.824s
user 0m20.911s
sys 0m2.494s
```

If I try and help DataFusion out by filtering out the null values before the join, the query takes 4x longer:

```
$ time bdt query --sql "select count(*) from web_sales join customer on web_sales.ws_bill_customer_sk = customer.c_customer_sk where web_sales.ws_bill_customer_sk is not null" --table customer.parquet --table web_sales.parquet
+-----------------+
| COUNT(UInt8(1)) |
+-----------------+
| 71983355 |
+-----------------+

real 0m3.413s
user 0m52.227s
sys 0m17.020s

```

**Describe the solution you'd like**
I plan on investigating this to understand why it is so slow and what we can do about it.

I am guessing that the filter is expensive because it is creating new batches and maybe the coalesce step as well. The join would just ignore the nulls and not create new batches so maybe that is just more efficient. Also, in this case it should be possible to push the filter down to the table scan but I am not sure that we have implemented that yet.

**Describe alternatives you've considered**
None

**Additional context**
None

Contributor guide

Open the contributing guide

Research direction

Reproduce the two bdt query commands and compare execution of the join, null filter, batch creation, coalesce, and table-scan paths. Profile the filter and join execution to identify why the filtered query is slower; done means the cause is documented with a focused regression test or an actionable fix direction.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust, sql
Domain
databases, performance
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.