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(HQLPreprocessor hqlp,
int joinSubstIndex,
RecordBuffer buffer,
boolean fine)
Analyze the property match expressions found in the current component's where clause or
join clause HQL, to determine suitability for a server-side join.
|
private boolean |
isLeadingIndexComponent(RecordBuffer buffer,
java.lang.String property)
Determine whether the given DMO property represents the leading component of any index
on the table represented by the given buffer.
|
private boolean |
isServerJoinPossible(java.util.List<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.List<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.List<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,
HQLPreprocessor hqlp,
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 isServerJoinPossible(java.util.List<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, HQLPreprocessor hqlp, 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
.hqlp
- HQL 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
admissible.fine
- true
if FINE level logging is enabled, else false
.true
if the join is recommended, false
if rejected.private boolean evaluatePropertyMatches(HQLPreprocessor hqlp, int joinSubstIndex, RecordBuffer buffer, boolean fine) throws PersistenceException
hqlp
- HQL 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 HQL
informs a decision to create a server-side join, else false
.PersistenceException
- if there is an error looking up index information.private boolean isLeadingIndexComponent(RecordBuffer buffer, java.lang.String property) throws PersistenceException
buffer
- Record buffer which represents the table associated with the property.property
- DMO property to be tested.true
if property
is a leading index component; else
false
.PersistenceException
- if there is an error looking up the backing table's indexes.private AdaptiveQuery serverJoinAdaptive(java.util.List<CompoundComponent> originals)
originals
- Compound query components which need to be joined.private PreselectQuery serverJoinPreselect(java.util.List<CompoundComponent> originals)
originals
- Compound query components which need to be joined.