private class CompoundQuery.Optimizer
extends java.lang.Object
AdaptiveQuery or PreselectQuery
(depending on whether the original compound query is set to preselect its results) from
the suitable candidates it finds. Only query components from adjacent loops are joined,
as many as possible while still maintaining the likelihood that the join will be performant
(which is the whole point of the optimization).
The analysis considers factors such as the type of iteration (NEXT, FIRST, LAST) of the original components, their substitution arguments, whether they utilize client-side filtering, the complexity of their where clauses, the columns on which they would join and the participation of those columns in database indexes, and of course whether the tables being queried reside in the same physical database.
Zero or more optimized joins may result from this analysis. If the algorithm determines no join is advisable, the original query components will be used unchanged. The algorithm will attempt to create as few, multi-table, server-side join queries as possible from the original components, ideally 1; however, the resulting, optimized queries may not represent the entire original query, or even adjacent sets of nested queries. For example, a compound query with 5 original components may be optimized to a single query representing all 5 tables; or a query for 2 of the tables and another for the other 3; 5 separate separate queries (i.e., the original state); 2 and 2; 4 and 1; etc. The original, enclosing compound query still will drive the record retrieval mechanics, it will just have fewer components to which it delegates the actual work.
| Modifier | Constructor and Description |
|---|---|
private |
Optimizer()
Constructor which immediately performs the analysis and if possible, the optimizations.
|
| Modifier and Type | Method and Description |
|---|---|
private boolean |
evaluatePropertyMatches(FQLPreprocessor fqlp,
int joinSubstIndex,
RecordBuffer buffer,
boolean fine)
Analyze the property match expressions found in the current component's where clause or
join clause FQL, to determine suitability for a server-side join.
|
private boolean |
hasSameSqlTable(CompoundComponent c1,
CompoundComponent c2)
Check if the two components use the same SQL table, in any referenced buffer.
|
private boolean |
isServerJoinPossible(java.util.ArrayList<CompoundComponent> candidates,
CompoundComponent nextComp,
boolean top,
int originalPosition)
Determine whether a server-side join is possible (and advisable) for the given component
and the zero or more candidates above it in the nesting.
|
private AdaptiveQuery |
serverJoinAdaptive(java.util.ArrayList<CompoundComponent> originals)
Create a multi-table, adaptive query from the given compound query components, which
will be joined at the database server.
|
private PreselectQuery |
serverJoinPreselect(java.util.ArrayList<CompoundComponent> originals)
Create a multi-table, preselect query from the given compound query components, which
will be joined at the database server.
|
private boolean |
validateJoin(Joinable parentQuery,
Joinable query,
java.lang.Object[] args,
Database database,
FQLPreprocessor fqlp,
boolean noOpenCrossJoin,
boolean fine)
Validate whether a server-side join between
parentQuery and
query is advisable to produce a performant result. |
private Optimizer()
private boolean hasSameSqlTable(CompoundComponent c1, CompoundComponent c2)
c1 - The first component.c2 - The second component.true if at least a buffer in one component has the same SQL name as in the other
component.private boolean isServerJoinPossible(java.util.ArrayList<CompoundComponent> candidates, CompoundComponent nextComp, boolean top, int originalPosition)
candidates - The list of candidate components, to the last of which the current candidate
(nextComp) will potentially have an upward join. This list may
be empty, indicating that nextComp is potentially the outermost
query being considered for the current group of components being joined. Each
component in the list represents a single-table component query. This argument
may not be null.nextComp - The single-table query currently being analyzed to join (upward) with the last
of the queries in the candidates list (if any), and potentially
downward with additional component queries (if any).top - true if this component and the list of candidates
are at the outermost nesting level.originalPosition - The one-based position of nextComp in the original list of query
components. Currently only used for debug logging.true if the algorithm has determined that nextComp
should be part of a server-side join.private boolean validateJoin(Joinable parentQuery, Joinable query, java.lang.Object[] args, Database database, FQLPreprocessor fqlp, boolean noOpenCrossJoin, boolean fine)
parentQuery and
query is advisable to produce a performant result. At this point, calling
code has determined the join is physically possible; it is this method's job to
determine whether this would be a good idea. The join may be rejected at this point due
to perceived where clause or join parameter complexity, poor matches of join columns,
etc.parentQuery - The nesting query.query - The nested query.args - Query substitution parameters, if any, for the originaly query.database - Database containing the tables referenced by parentQuery and
query.fqlp - FQL preprocessor used in the analysis of the query's where clause, if any. May
by null.noOpenCrossJoin - true if an unrestricted cross join from query to
parentQuery must be rejected; false if it is
permissible.fine - true if FINE level logging is enabled, else false.true if the join is recommended, false if rejected.private boolean evaluatePropertyMatches(FQLPreprocessor fqlp, int joinSubstIndex, RecordBuffer buffer, boolean fine) throws PersistenceException
fqlp - FQL preprocessor which has parsed the where or join clause.joinSubstIndex - Index of the substitution parameter which represents the field reference used
to join the table referenced by the current query to the table in the nesting
query above it.buffer - Record buffer referenced by the current query.fine - true if FINE level logging is enabled, else false.true if an analysis of the property match expressions in the FQL
informs a decision to create a server-side join, else false.PersistenceException - if there is an error looking up index information.private AdaptiveQuery serverJoinAdaptive(java.util.ArrayList<CompoundComponent> originals)
originals - Compound query components which need to be joined.AdaptiveQuery detects that it
is not able to be properly optimized, this will return null instead.private PreselectQuery serverJoinPreselect(java.util.ArrayList<CompoundComponent> originals)
originals - Compound query components which need to be joined.