mirror of https://gitee.com/bigwinds/arangodb
make use of projections if the projected data is used by an IndexNode's condition (#8001)
This commit is contained in:
parent
7958ac1a68
commit
cabeb8fc7b
|
@ -145,6 +145,22 @@ void RocksDBOptimizerRules::reduceExtractionToProjectionRule(
|
||||||
attributes.emplace(it.attributePath[0]);
|
attributes.emplace(it.attributePath[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (current->getType() == EN::INDEX) {
|
||||||
|
Condition const* condition = ExecutionNode::castTo<IndexNode const*>(current)->condition();
|
||||||
|
|
||||||
|
if (condition != nullptr && condition->root() != nullptr) {
|
||||||
|
AstNode const* node = condition->root();
|
||||||
|
vars.clear();
|
||||||
|
current->getVariablesUsedHere(vars);
|
||||||
|
|
||||||
|
if (vars.find(v) != vars.end()) {
|
||||||
|
if (!Ast::getReferencedAttributes(node, v, attributes)) {
|
||||||
|
stop = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
optimize = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// all other node types mandate a check
|
// all other node types mandate a check
|
||||||
doRegularCheck = true;
|
doRegularCheck = true;
|
||||||
|
@ -170,12 +186,8 @@ void RocksDBOptimizerRules::reduceExtractionToProjectionRule(
|
||||||
|
|
||||||
// projections are currently limited (arbitrarily to 5 attributes)
|
// projections are currently limited (arbitrarily to 5 attributes)
|
||||||
if (optimize && !stop && !attributes.empty() && attributes.size() <= 5) {
|
if (optimize && !stop && !attributes.empty() && attributes.size() <= 5) {
|
||||||
std::vector<std::string> r;
|
|
||||||
for (auto& it : attributes) {
|
|
||||||
r.emplace_back(std::move(it));
|
|
||||||
}
|
|
||||||
// store projections in DocumentProducingNode
|
// store projections in DocumentProducingNode
|
||||||
e->projections(std::move(r));
|
e->projections(std::move(attributes));
|
||||||
|
|
||||||
if (n->getType() == ExecutionNode::INDEX) {
|
if (n->getType() == ExecutionNode::INDEX) {
|
||||||
// need to update _indexCoversProjections value in an IndexNode
|
// need to update _indexCoversProjections value in an IndexNode
|
||||||
|
|
|
@ -288,7 +288,6 @@ bool RocksDBPrimaryIndexInIterator::nextCovering(DocumentCallback const& cb, siz
|
||||||
}
|
}
|
||||||
|
|
||||||
while (limit > 0) {
|
while (limit > 0) {
|
||||||
// TODO: prevent copying of the value into result, as we don't need it here!
|
|
||||||
LocalDocumentId documentId = _index->lookupKey(_trx, StringRef(*_iterator));
|
LocalDocumentId documentId = _index->lookupKey(_trx, StringRef(*_iterator));
|
||||||
if (documentId.isSet()) {
|
if (documentId.isSet()) {
|
||||||
cb(documentId, *_iterator);
|
cb(documentId, *_iterator);
|
||||||
|
|
|
@ -228,15 +228,36 @@ function optimizerRuleTestSuite () {
|
||||||
result = AQL_EXECUTE(query[0], { "@cn" : cn });
|
result = AQL_EXECUTE(query[0], { "@cn" : cn });
|
||||||
assertEqual(query[1], result.json);
|
assertEqual(query[1], result.json);
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
testJoin : function () {
|
||||||
|
c.ensureIndex({ type: "skiplist", fields: ["value"] });
|
||||||
|
|
||||||
|
let queries = [
|
||||||
|
"FOR doc1 IN @@cn FOR doc2 IN @@cn FILTER doc1.value == doc2._key RETURN [doc1._key, doc2._key]",
|
||||||
|
"FOR doc1 IN @@cn FOR doc2 IN @@cn FILTER doc1.value == doc2._key RETURN [doc1.value, doc2._key]",
|
||||||
|
];
|
||||||
|
|
||||||
|
queries.forEach(function(query) {
|
||||||
|
let result = AQL_EXPLAIN(query, { "@cn" : cn });
|
||||||
|
assertNotEqual(-1, result.plan.rules.indexOf(ruleName), query);
|
||||||
|
|
||||||
|
let found = 0;
|
||||||
|
result.plan.nodes.filter(function(node) {
|
||||||
|
return node.type === 'IndexNode' || node.type === 'EnumerateCollectionNode';
|
||||||
|
}).forEach(function(node) {
|
||||||
|
assertNotEqual([], node.projections);
|
||||||
|
++found;
|
||||||
|
});
|
||||||
|
|
||||||
|
assertEqual(2, found);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief executes the test suite
|
/// @brief executes the test suite
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
jsunity.run(optimizerRuleTestSuite);
|
jsunity.run(optimizerRuleTestSuite);
|
||||||
|
|
||||||
return jsunity.done();
|
return jsunity.done();
|
||||||
|
|
Loading…
Reference in New Issue