You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: rfcs/1-distributed-dynamic-filtering.md
+37-25Lines changed: 37 additions & 25 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -3,9 +3,21 @@
3
3
## Contents
4
4
5
5
1. Background - Dynamic Filtering in Vanilla DataFusion
6
-
2. Background - Dynamic Filtering in Trino and Spark
7
-
2. Dynamic Filtering in Distributed DataFusion - Proposed Highlevel Design
8
-
3. Gaps to Address in Vanilla DataFusion - What's blocking us?
6
+
- "Global" Dynamic Filters
7
+
- "Partition-Aware" Dynamic Filters
8
+
2. Background - Dynamic Filtering in Trino and Spark
9
+
- Trino
10
+
- Spark
11
+
3. Distributed Dynamic Filters
12
+
- Local Case
13
+
- Remote Case
14
+
4. Implementation Details
15
+
- Extracting Dynamic Filters
16
+
- Routing Dynamic Filters
17
+
- Displaying Dynamic Filters
18
+
5. Gaps in Vanilla DataFusion
19
+
- Getting `&DynamicFilterPhysicalExpr` from `ExecutionPlan`
20
+
- Merging Dynamic Filters
9
21
10
22
## 1. Background - Dynamic Filtering in Vanilla DataFusion
11
23
@@ -30,7 +42,7 @@ CASE hash(expr) % N
30
42
Ultimately, they are just an optimization over "global" dynamic filters because they make the filters
31
43
more granular, letting us prune more efficiently.
32
44
33
-
### "Global" dynamic filter
45
+
### "Global" Dynamic Filters
34
46
```
35
47
DynamicFilterPhysicalExpr:
36
48
┌────────────────────────┐
@@ -53,7 +65,7 @@ more granular, letting us prune more efficiently.
53
65
└──────────────────────────┘
54
66
```
55
67
56
-
### "Partition-Aware Dynamic Filter"
68
+
### "Partition-Aware" Dynamic Filter
57
69
```
58
70
DynamicFilterPhysicalExpr:
59
71
┌────────────────────────┐
@@ -266,18 +278,18 @@ consumers may prune rows incorrectly.
266
278
267
279
Consider if these "global" dynamic filters generated in stage 2
268
280
269
-
Task 1: `DynamicFilterPhysicalExpr: a@0 >= v0 AND a@0 <= v1`
270
-
Task 2: `DynamicFilterPhysicalExpr: a@0 >= v2`
271
-
Task 3: `DynamicFilterPhysicalExpr: a@0 IN LIST [v3, v4 ...]`
281
+
Task 1: `DynamicFilterPhysicalExpr: a@0 >= v0 AND a@0 <= v1`
282
+
Task 2: `DynamicFilterPhysicalExpr: a@0 >= v2`
283
+
Task 3: `DynamicFilterPhysicalExpr: a@0 IN LIST [v3, v4 ...]`
272
284
273
285
What is the correct filter to push to Stage 1 Task 1 and Stage 1 Task 2?
274
286
275
287
##### Option 1: OR the Filters Together
276
288
277
289
`DynamicFilterPhysicalExpr: a@0 >= v0 AND a@0 <= v1 OR a@0 >= v2 OR a@0 IN LIST [v3, v4 ...]`
278
290
279
-
Pros:
280
-
It's simple.
291
+
Pros:
292
+
-It's simple.
281
293
282
294
Cons:
283
295
- Loss of selectivity (not worse than single node execution which would have had one filter anyways). We may allow a row to pass a filter due to
@@ -290,17 +302,17 @@ Cons:
290
302
291
303
Similar to the above except you try to avoid ORing.
292
304
293
-
We could try converting these filters from this
294
-
`DynamicFilterPhysicalExpr: a@0 >= 0 AND a@0 <= 5 OR IN LIST [10, 11]`
295
-
`DynamicFilterPhysicalExpr: a@0 >= 1 AND a@0 <= 10 OR IN LIST [12, 13]`
305
+
We could try converting these filters from this
306
+
`DynamicFilterPhysicalExpr: a@0 >= 0 AND a@0 <= 5 OR IN LIST [10, 11]`
307
+
`DynamicFilterPhysicalExpr: a@0 >= 1 AND a@0 <= 10 OR IN LIST [12, 13]`
296
308
297
-
To this
309
+
To this
298
310
`DynamicFilterPhysicalExpr: a@0 >= 0 AND a@0 <= 10 OR IN LIST [10, 11, 12, 13]`
299
311
300
-
Pros:
312
+
Pros:
301
313
- Less overhead than ORing
302
314
303
-
Cons:
315
+
Cons:
304
316
- Is brittle. What if we have to support non-range and non-IN-LIST expressions? It would be nice if dynamic filters in vanilla datafusion natively implemented a `merge` or `union` operation
305
317
so we didn't have to worry about it.
306
318
@@ -381,10 +393,10 @@ CASE Range(a@0)
381
393
WHEN 0: v1 <= a@0 < v2 // distinct range
382
394
```
383
395
384
-
Pros:
396
+
Pros:
385
397
- Simple.
386
398
387
-
Cons:
399
+
Cons:
388
400
- It relies on some subtle properties. When will this stop working?
389
401
- If the hash repartitions below `NetworkShuffleExec`s produce a partition count that is not a multiple of `target_partitions`.
390
402
[Here](https://github.com/datafusion-contrib/datafusion-distributed/blob/a6c326807fa3a5ff05b4b7e08a1bd1e3cd7bfe53/src/execution_plans/network_shuffle.rs?plain=1#L160) is where we scale up the `RepartitionExec` today
@@ -401,16 +413,16 @@ WHEN 0: a@0 >= v0 AND a@0 <= v1 OR a@0 IN LIST [v2, v3, v4 ...] OR a@0 >= v6
401
413
WHEN 1: ... OR ... OR ...
402
414
```
403
415
404
-
Pros
416
+
Pros:
405
417
- Filter evaluation may be cheaper
406
418
407
-
Cons
419
+
Cons:
408
420
- It's a bit brittle. We would need to manually modify `PhysicalExpr`s.
409
421
410
422
##### Proposal
411
423
412
424
This RFC proposes that we `OR` the cases together. If loss of selectivity is a conern, this can be addressed in a future implementation of distributed dynamic filtering. In the future,
413
-
supporting an official `union()` or `merge()` operation for dynamic filters in vanilla datafusion would be a nice addition so we don't have to perform "expression surgery" in datafusion-distributed.
425
+
supporting an official `union()` or `merge()` operation for dynamic filters which does a case-wise merge in vanilla datafusion would be a nice addition so we don't have to perform "expression surgery" in datafusion-distributed.
414
426
This is discussed in the `Merging Dynamic Filters` section below.
415
427
416
428
```
@@ -473,7 +485,7 @@ This is discussed in the `Merging Dynamic Filters` section below.
473
485
```
474
486
475
487
476
-
## Implementation Details
488
+
## 4. Implementation Details
477
489
478
490
### Extracting Dynamic Filters
479
491
@@ -506,7 +518,7 @@ dynamic filter pruning work during execution, after execution we must propagate
0 commit comments