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); registerRule("move-filters-up", moveFiltersUpRule, 20);
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
/// "Pass 2": interchange EnumerateCollection nodes in all possible ways /// "Pass 2": try to remove redundant or unnecessary nodes
/// 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
/// use levels between 101 and 199 for this /// use levels between 101 and 199 for this
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -214,15 +205,58 @@ void Optimizer::setupRules () {
registerRule("remove-redundant-sorts", removeRedundantSorts, 130); registerRule("remove-redundant-sorts", removeRedundantSorts, 130);
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
/// "Pass 4": use indexes if possible for FILTER and/or SORT nodes /// "Pass 3": interchange EnumerateCollection nodes in all possible ways
/// use levels between 200 and 299 for this /// 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 . . . // 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 // 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: // Now sort them by level:
std::stable_sort(_rules.begin(), _rules.end()); std::stable_sort(_rules.begin(), _rules.end());

View File

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