mirror of https://gitee.com/bigwinds/arangodb
Add filter rule which moves Filters & Calculations into the parts of a Plan that is distributed to clusters.
This commit is contained in:
parent
f0e6356695
commit
6c81f630a3
|
@ -454,6 +454,14 @@ void Optimizer::setupRules () {
|
||||||
distributeInCluster_pass10,
|
distributeInCluster_pass10,
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (triagens::arango::ServerState::instance()->isCoordinator()) {
|
||||||
|
// distribute operations in cluster
|
||||||
|
registerRule("distribute-filtercalc-to-cluster",
|
||||||
|
distributeFilternCalcToCluster,
|
||||||
|
distributeFilternCalcToCluster_pass10,
|
||||||
|
false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Local Variables:
|
// Local Variables:
|
||||||
|
|
|
@ -136,8 +136,12 @@ namespace triagens {
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// make operations on sharded collections use scatter / gather / remote
|
// make operations on sharded collections use scatter / gather / remote
|
||||||
distributeInCluster_pass10 = 1000
|
distributeInCluster_pass10 = 1000,
|
||||||
|
|
||||||
|
// move FilterNodes & Calculation nodes inbetween
|
||||||
|
// scatter(remote) <-> gather(remote) so they're
|
||||||
|
// distributed to the cluster nodes.
|
||||||
|
distributeFilternCalcToCluster_pass10 = 1010
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -1681,6 +1681,88 @@ int triagens::aql::distributeInCluster (Optimizer* opt,
|
||||||
return TRI_ERROR_NO_ERROR;
|
return TRI_ERROR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief move filters up in the plan
|
||||||
|
/// this rule modifies the plan in place
|
||||||
|
/// filters are moved as far up in the plan as possible to make result sets
|
||||||
|
/// as small as possible as early as possible
|
||||||
|
/// filters are not pushed beyond limits
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
int triagens::aql::distributeFilternCalcToCluster (Optimizer* opt,
|
||||||
|
ExecutionPlan* plan,
|
||||||
|
Optimizer::Rule const* rule) {
|
||||||
|
bool modified = false;
|
||||||
|
|
||||||
|
std::vector<ExecutionNode*> nodes
|
||||||
|
= plan->findNodesOfType(triagens::aql::ExecutionNode::GATHER, true);
|
||||||
|
|
||||||
|
|
||||||
|
for (auto n : nodes) {
|
||||||
|
auto remoteNodeList = n->getDependencies();
|
||||||
|
TRI_ASSERT(remoteNodeList.size() > 0);
|
||||||
|
auto rn = remoteNodeList[0];
|
||||||
|
auto parents = n->getParents();
|
||||||
|
if (parents.size() < 1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
while (1) {
|
||||||
|
bool stopSearching = false;
|
||||||
|
|
||||||
|
auto inspectNode = parents[0];
|
||||||
|
|
||||||
|
switch (inspectNode->getType()) {
|
||||||
|
case EN::ENUMERATE_LIST:
|
||||||
|
case EN::SINGLETON:
|
||||||
|
case EN::AGGREGATE:
|
||||||
|
case EN::INSERT:
|
||||||
|
case EN::REMOVE:
|
||||||
|
case EN::REPLACE:
|
||||||
|
case EN::UPDATE:
|
||||||
|
parents = inspectNode->getParents();
|
||||||
|
continue;
|
||||||
|
case EN::SUBQUERY:
|
||||||
|
case EN::RETURN:
|
||||||
|
case EN::NORESULTS:
|
||||||
|
case EN::SCATTER:
|
||||||
|
case EN::GATHER:
|
||||||
|
case EN::ILLEGAL:
|
||||||
|
//do break
|
||||||
|
case EN::REMOTE:
|
||||||
|
case EN::LIMIT:
|
||||||
|
case EN::SORT:
|
||||||
|
case EN::INDEX_RANGE:
|
||||||
|
case EN::ENUMERATE_COLLECTION:
|
||||||
|
stopSearching = true;
|
||||||
|
break;
|
||||||
|
case EN::CALCULATION:
|
||||||
|
case EN::FILTER:
|
||||||
|
// remember our cursor...
|
||||||
|
parents = inspectNode->getParents();
|
||||||
|
// then unlink the filter/calculator from the plan
|
||||||
|
plan->unlinkNode(inspectNode);
|
||||||
|
// and re-insert into plan in front of the remoteNode
|
||||||
|
plan->insertDependency(rn, inspectNode);
|
||||||
|
|
||||||
|
modified = true;
|
||||||
|
//ready to rumble!
|
||||||
|
};
|
||||||
|
if (stopSearching) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (modified) {
|
||||||
|
plan->findVarUsage();
|
||||||
|
}
|
||||||
|
|
||||||
|
opt->addPlan(plan, rule->level, modified);
|
||||||
|
|
||||||
|
return TRI_ERROR_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
// Local Variables:
|
// Local Variables:
|
||||||
// mode: outline-minor
|
// mode: outline-minor
|
||||||
// outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|// --SECTION--\\|/// @\\}\\)"
|
// outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|// --SECTION--\\|/// @\\}\\)"
|
||||||
|
|
|
@ -112,6 +112,7 @@ namespace triagens {
|
||||||
|
|
||||||
int distributeInCluster (Optimizer*, ExecutionPlan*, Optimizer::Rule const*);
|
int distributeInCluster (Optimizer*, ExecutionPlan*, Optimizer::Rule const*);
|
||||||
|
|
||||||
|
int distributeFilternCalcToCluster (Optimizer*, ExecutionPlan*, Optimizer::Rule const*);
|
||||||
} // namespace aql
|
} // namespace aql
|
||||||
} // namespace triagens
|
} // namespace triagens
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue