Class JoinFilterAnalyzer
java.lang.Object
org.apache.druid.segment.join.filter.JoinFilterAnalyzer
When there is a filter in a join query, we can sometimes improve performance by applying parts of the filter
when we first read from the base table instead of after the join.
The first step of the filter splitting is to convert the filter into
https://en.wikipedia.org/wiki/Conjunctive_normal_form (an AND of ORs). This allows us to consider each
OR clause independently as a candidate for filter push down to the base table.
A filter clause can be pushed down if it meets one of the following conditions:
- The filter only applies to columns from the base table
- The filter applies to columns from the join table, and we determine that the filter can be rewritten
into a filter on columns from the base table
For the second case, where we rewrite filter clauses, the rewritten clause can be less selective than the original,
so we preserve the original clause in the post-join filtering phase.
The starting point for join analysis is the
computeJoinFilterPreAnalysis(org.apache.druid.segment.join.filter.JoinFilterPreAnalysisKey) method. This method should be
called before performing any per-segment join query work. This method converts the query filter into
conjunctive normal form, and splits the CNF clauses into a portion that only references base table columns and
a portion that references join table columns. For the filter clauses that apply to join table columns, the
pre-analysis step computes the information necessary for rewriting such filters into filters on base table columns.
The result of this pre-analysis method should be passed into the next step of join filter analysis, described below.
The splitFilter(JoinFilterPreAnalysis, Filter) method takes the pre-analysis result and optionally applies
the filter rewrite and push down operations on a per-segment level.-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionstatic JoinFilterPreAnalysisBefore making per-segment filter splitting decisions, we first do a pre-analysis step where we convert the query filter (if any) into conjunctive normal form and then determine the structure of RHS filter rewrites (if any), since this information is shared across all per-segment operations.static JoinFilterSplitsplitFilter(JoinFilterPreAnalysis joinFilterPreAnalysis, Filter baseFilter)
-
Constructor Details
-
JoinFilterAnalyzer
public JoinFilterAnalyzer()
-
-
Method Details
-
computeJoinFilterPreAnalysis
Before making per-segment filter splitting decisions, we first do a pre-analysis step where we convert the query filter (if any) into conjunctive normal form and then determine the structure of RHS filter rewrites (if any), since this information is shared across all per-segment operations. SeeJoinFilterPreAnalysisfor details on the result of this pre-analysis step.- Parameters:
key- All the information needed to pre-analyze a filter- Returns:
- A JoinFilterPreAnalysis containing information determined in this pre-analysis step.
-
splitFilter
public static JoinFilterSplit splitFilter(JoinFilterPreAnalysis joinFilterPreAnalysis, @Nullable Filter baseFilter) - Parameters:
joinFilterPreAnalysis- The pre-analysis computed by {@link #computeJoinFilterPreAnalysis)}baseFilter- - Filter on base table that was specified in the query itself- Returns:
- A JoinFilterSplit indicating what parts of the filter should be applied pre-join and post-join
-