1
0
Fork 0

Rearrange levels for optimizer rules. Use rules multiple times.

This commit is contained in:
Max Neunhoeffer 2014-08-28 13:46:46 +02:00
parent e1b557ff20
commit 9b49328218
2 changed files with 56 additions and 19 deletions

View File

@ -188,16 +188,7 @@ void Optimizer::setupRules () {
registerRule("move-filters-up", moveFiltersUpRule, 20);
//////////////////////////////////////////////////////////////////////////////
/// "Pass 2": interchange EnumerateCollection nodes in all possible ways
/// this is level 100, please never let new plans from higher
/// levels go back to this or lower levels!
//////////////////////////////////////////////////////////////////////////////
registerRule("interchangeAdjacentEnumerations",
interchangeAdjacentEnumerations, 100);
//////////////////////////////////////////////////////////////////////////////
/// "Pass 3": try to remove redundant or unnecessary nodes
/// "Pass 2": try to remove redundant or unnecessary nodes
/// use levels between 101 and 199 for this
//////////////////////////////////////////////////////////////////////////////
@ -214,15 +205,58 @@ void Optimizer::setupRules () {
registerRule("remove-redundant-sorts", removeRedundantSorts, 130);
//////////////////////////////////////////////////////////////////////////////
/// "Pass 4": use indexes if possible for FILTER and/or SORT nodes
/// use levels between 200 and 299 for this
/// "Pass 3": interchange EnumerateCollection nodes in all possible ways
/// this is level 500, please never let new plans from higher
/// levels go back to this or lower levels!
//////////////////////////////////////////////////////////////////////////////
registerRule("interchangeAdjacentEnumerations",
interchangeAdjacentEnumerations, 500);
//////////////////////////////////////////////////////////////////////////////
// "Pass 4": moving nodes "up" (potentially outside loops) (second try):
// please use levels between 501 and 599 here
//////////////////////////////////////////////////////////////////////////////
// move calculations up the dependency chain (to pull them out of
// inner loops etc.)
registerRule("move-calculations-up", moveCalculationsUpRule, 510);
// move filters up the dependency chain (to make result sets as small
// as possible as early as possible)
registerRule("move-filters-up", moveFiltersUpRule, 520);
//////////////////////////////////////////////////////////////////////////////
/// "Pass 5": try to remove redundant or unnecessary nodes (second try)
/// use levels between 601 and 699 for this
//////////////////////////////////////////////////////////////////////////////
// remove filters from the query that are not necessary at all
// filters that are always true will be removed entirely
// filters that are always false will be replaced with a NoResults node
registerRule("remove-unnecessary-filters", removeUnnecessaryFiltersRule, 610);
// remove calculations that are never necessary
registerRule("remove-unnecessary-calculations",
removeUnnecessaryCalculationsRule, 620);
// remove redundant sort blocks
registerRule("remove-redundant-sorts", removeRedundantSorts, 630);
//////////////////////////////////////////////////////////////////////////////
/// "Pass 6": use indexes if possible for FILTER and/or SORT nodes
/// use levels between 701 and 799 for this
//////////////////////////////////////////////////////////////////////////////
// try to find a filter after an enumerate collection and find an index . . .
registerRule("use-index-range", useIndexRange, 210);
registerRule("use-index-range", useIndexRange, 710);
// try to find sort blocks which are superseeded by indexes
registerRule("use-index-for-sort", useIndexForSort, 220);
registerRule("use-index-for-sort", useIndexForSort, 720);
//////////////////////////////////////////////////////////////////////////////
/// END OF OPTIMISATIONS
//////////////////////////////////////////////////////////////////////////////
// Now sort them by level:
std::stable_sort(_rules.begin(), _rules.end());

View File

@ -725,14 +725,17 @@ class sortToIndexNode : public WalkerWorker<ExecutionNode> {
ExecutionPlan* _plan;
Optimizer::PlanList& _out;
sortAnalysis* _sortNode;
int _level;
public:
sortToIndexNode (ExecutionPlan* plan,
Optimizer::PlanList& out,
sortAnalysis* Node)
sortAnalysis* Node,
int level)
: _plan(plan),
_out(out),
_sortNode(Node) {
_sortNode(Node),
_level(level) {
}
////////////////////////////////////////////////////////////////////////////////
@ -751,7 +754,7 @@ class sortToIndexNode : public WalkerWorker<ExecutionNode> {
////////////////////////////////////////////////////////////////////////////////
/// @brief check whether we can sort via an index.
////////////////////////////////////////////////////////////////////////////////
bool handleEnumerateCollectionNode(EnumerateCollectionNode* node)
bool handleEnumerateCollectionNode(EnumerateCollectionNode* node, int level)
{
auto variableName = node->getVariablesSetHere()[0]->name;
auto result = _sortNode->getAttrsForVariableName(variableName);
@ -836,7 +839,7 @@ class sortToIndexNode : public WalkerWorker<ExecutionNode> {
return handleIndexRangeNode(static_cast<IndexRangeNode*>(en));
case EN::ENUMERATE_COLLECTION:
return handleEnumerateCollectionNode(static_cast<EnumerateCollectionNode*>(en));
return handleEnumerateCollectionNode(static_cast<EnumerateCollectionNode*>(en), _level);
}
return true;
}
@ -852,7 +855,7 @@ int triagens::aql::useIndexForSort (Optimizer* opt,
auto thisSortNode = static_cast<SortNode*>(n);
sortAnalysis node(thisSortNode);
if (node.isAnalyzeable()) {
sortToIndexNode finder(plan, out, &node);
sortToIndexNode finder(plan, out, &node, level);
thisSortNode->walk(&finder);/// todo auf der dependency anfangen
}
}