Skip to content

Commit

Permalink
add optimizer comments (#3910)
Browse files Browse the repository at this point in the history
* small format

* add comments for EliminateRowCollectRule

* add comments for MergeGetNbrsAndDedupRule

* add comments for MergeGetNbrsAndDedupRule

* add comments for MergeGetNbrsAndProjectRule

* add comments for MergeGetVerticesAndDedupRule

* add comments for MergeGetVerticesAndProjectRule

* add comments for PushFilterDownAggregateRule

* add comments for PushFilterDownGetNbrsRule

* add comments for PushFilterDownLeftJoinRule

* add comments for PushFilterDownProjectRule

* add comments for PushFilterDownScanVerticesRule

* add comments for PushFilterDownGetNeighborsRule

* add comments for PushLimitDownGetNeighborsRule

* add comments for PushLimitDownIndexScanRule

* tmp

* add comments for PushLimitDownScanAppendVerticesRule

* add comments for PushLimitDownScanEdgesAppendVerticesRule

* PushStepLimitDownGetNeighborsRule

* add comments for PushStepSampleDownGetNeighborsRule

* add comments for TopNrule

* add comments for PushTopNDownIndexScanRule

* add comments for PushVFilterDownScanVerticesRule

* add comments for RemoveNoopProjectRule

* small comments

* add comments for getEdgesTransformRule

* add comments for IndexScanRule

* small comments

* add comments for memo operations

* small delete

* format

Co-authored-by: Yee <2520865+yixinglu@users.noreply.github.com>
Co-authored-by: Sophie <84560950+Sophie-Xie@users.noreply.github.com>
  • Loading branch information
3 people authored Mar 15, 2022
1 parent 2c7b388 commit 9a401f7
Show file tree
Hide file tree
Showing 36 changed files with 736 additions and 14 deletions.
2 changes: 2 additions & 0 deletions src/graph/optimizer/OptContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,10 @@ class OptContext final : private boost::noncopyable, private cpp::NonMovable {
const OptGroupNode *findOptGroupNodeByPlanNodeId(int64_t planNodeId) const;

private:
// A global flag to record whether this iteration caused a change to the plan
bool changed_{true};
graph::QueryContext *qctx_{nullptr};
// Memo memory management in the Optimizer phase
std::unique_ptr<ObjectPool> objPool_;
std::unordered_map<int64_t, const OptGroupNode *> planNodeToOptGroupNodeMap_;
};
Expand Down
6 changes: 6 additions & 0 deletions src/graph/optimizer/Optimizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ namespace opt {

Optimizer::Optimizer(std::vector<const RuleSet *> ruleSets) : ruleSets_(std::move(ruleSets)) {}

// Optimizer entrance
StatusOr<const PlanNode *> Optimizer::findBestPlan(QueryContext *qctx) {
DCHECK(qctx != nullptr);
auto optCtx = std::make_unique<OptContext>(qctx);
Expand All @@ -49,6 +50,7 @@ StatusOr<const PlanNode *> Optimizer::findBestPlan(QueryContext *qctx) {
return newRoot;
}

// Just for Properties Pruning
Status Optimizer::postprocess(PlanNode *root, graph::QueryContext *qctx, GraphSpaceID spaceID) {
if (FLAGS_enable_optimizer_property_pruner_rule) {
graph::PropertyTracker propsUsed;
Expand All @@ -67,12 +69,15 @@ StatusOr<OptGroup *> Optimizer::prepare(OptContext *ctx, PlanNode *root) {
}

Status Optimizer::doExploration(OptContext *octx, OptGroup *rootGroup) {
// Terminate when the maximum number of iterations(RuleSets) is reached or the execution plan is
// unchanged
int8_t appliedTimes = kMaxIterationRound;
while (octx->changed()) {
if (--appliedTimes < 0) break;
octx->setChanged(false);
for (auto ruleSet : ruleSets_) {
for (auto rule : ruleSet->rules()) {
// Explore until the maximum number of iterations(Rules) is reached
NG_RETURN_IF_ERROR(rootGroup->exploreUntilMaxRound(rule));
rootGroup->setUnexplored(rule);
}
Expand All @@ -81,6 +86,7 @@ Status Optimizer::doExploration(OptContext *octx, OptGroup *rootGroup) {
return Status::OK();
}

// Create Memo structure
OptGroup *Optimizer::convertToGroup(OptContext *ctx,
PlanNode *node,
std::unordered_map<int64_t, OptGroup *> *visited) {
Expand Down
37 changes: 28 additions & 9 deletions src/graph/optimizer/rule/CollapseProjectRule.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,34 @@ DECLARE_bool(enable_optimizer_collapse_project_rule);
namespace nebula {
namespace opt {

/**
* Combines two [[Project]] nodes into one
* Required conditions:
* 1. Match the pattern
* 2. Expressions between nodes cannot be referenced more than once
* Benefits:
* 1. reduce the copy of memory between nodes
* 2. reduces expression overhead in some cases(similar to column pruning)
*/
// Combines two [[Project]] nodes into one
// Required conditions:
// 1. Match the pattern
// 2. Expressions between nodes cannot be referenced more than once
// Benefits:
// 1. reduce the copy of memory between nodes
// 2. reduces expression overhead in some cases(similar to column pruning)
//
// Tranformation:
// Before:
//
// +------------+------------+
// | Project |
// | ($A1+1 AS A2,$B1 AS B2) |
// +------------+------------+
// |
// +-------------------+-------------------+
// | Project |
// | ($v.age+1 AS A1,$v AS B1,$n.age AS C1)|
// +-------------------+-------------------+
//
// After:
//
// +--------------+--------------+
// | Project |
// | ($v.age+1+1 AS A2,$v AS B2) |
// +--------------+--------------+
//

class CollapseProjectRule final : public OptRule {
public:
Expand Down
24 changes: 24 additions & 0 deletions src/graph/optimizer/rule/CombineFilterRule.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,30 @@
namespace nebula {
namespace opt {

// Combines two [[Filter]] nodes into one and connect the filter expressions with `LogicalAnd`
// Required conditions:
// 1. Match the pattern
// Benefits:
// 1. reduces the expression iterated times
//
// Tranformation:
// Before:
//
// +-----+-----+
// | Filter(A) |
// +-----+-----+
// |
// +-----+-----+
// | Filter(B) |
// +-----+-----+
//
// After:
//
// +--------+--------+
// | Filter(A and B) |
// +--------+--------+
//

class CombineFilterRule final : public OptRule {
public:
const Pattern &pattern() const override;
Expand Down
1 change: 1 addition & 0 deletions src/graph/optimizer/rule/EdgeIndexFullScanRule.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
namespace nebula {
namespace opt {

// Apply the transformation of base class(IndexFullScanBaseRule::transform)
class EdgeIndexFullScanRule final : public IndexFullScanBaseRule {
public:
const Pattern& pattern() const override;
Expand Down
24 changes: 24 additions & 0 deletions src/graph/optimizer/rule/EliminateRowCollectRule.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,30 @@
namespace nebula {
namespace opt {

// Eliminate useless [[DataCollect]] node
// Required conditions:
// 1. Match the pattern
// 2. DataCollect::DCKind is `kRowBasedMove`
// Benefits:
// 1. Delete unnecessary node
//
// Tranformation:
// Before:
//
// +------+------+
// | DataCollect |
// +------+------+
// |
// +------+------+
// | Project |
// +------+------+
//
// After:
//
// +------+------+
// | Project |
// +------+------+

class EliminateRowCollectRule final : public OptRule {
public:
const Pattern &pattern() const override;
Expand Down
1 change: 1 addition & 0 deletions src/graph/optimizer/rule/GeoPredicateEdgeIndexScanRule.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
namespace nebula {
namespace opt {

// Apply the transformation of base class(GeoPredicateIndexScanBaseRule::transform)
class GeoPredicateEdgeIndexScanRule final : public GeoPredicateIndexScanBaseRule {
public:
const Pattern &pattern() const override;
Expand Down
1 change: 1 addition & 0 deletions src/graph/optimizer/rule/GeoPredicateTagIndexScanRule.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
namespace nebula {
namespace opt {

// Apply the transformation of base class(GeoPredicateIndexScanBaseRule::transform)
class GeoPredicateTagIndexScanRule final : public GeoPredicateIndexScanBaseRule {
public:
const Pattern &pattern() const override;
Expand Down
1 change: 1 addition & 0 deletions src/graph/optimizer/rule/GetEdgesTransformRule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ bool GetEdgesTransformRule::match(OptContext *ctx, const MatchedResult &matched)
const auto &colNames = traverse->colNames();
auto colSize = colNames.size();
DCHECK_GE(colSize, 2);
// TODO: Poor readability for optimizer, is there any other way to do the same thing?
if (colNames[colSize - 2][0] != '_') { // src
return false;
}
Expand Down
39 changes: 37 additions & 2 deletions src/graph/optimizer/rule/GetEdgesTransformRule.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,43 @@ class PlanNode;

namespace opt {

// e.g. match ()-[e]->(?) return e
// Optimize to get edges directly
// Convert [[ScanVertices]] to [[ScanEdges]] in certain cases
// Required conditions:
// 1. Match the pattern
// Benefits:
// 1. Avoid doing Traverse to optimize performance
// Quey example:
// 1. match ()-[e]->() return e limit 3
//
// Tranformation:
// Before:
//
// +---------+---------+
// | AppendVertices |
// +---------+---------+
// |
// +---------+---------+
// | Traverse |
// +---------+---------+
// |
// +---------+---------+
// | ScanVertices |
// +---------+---------+
//
// After:
//
// +---------+---------+
// | AppendVertices |
// +---------+---------+
// |
// +---------+---------+
// | Project |
// +---------+---------+
// |
// +---------+---------+
// | ScanEdges |
// +---------+---------+

class GetEdgesTransformRule final : public OptRule {
public:
const Pattern &pattern() const override;
Expand Down
5 changes: 4 additions & 1 deletion src/graph/optimizer/rule/IndexScanRule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ StatusOr<OptRule::TransformResult> IndexScanRule::transform(OptContext* ctx,
NG_RETURN_IF_ERROR(analyzeExpression(newFilter, &items, &kind, isEdge(groupNode), qctx));
auto status = createIndexQueryCtx(iqctx, kind, items, qctx, groupNode);
if (!status.ok()) {
// Degenerate back to tag lookup
NG_RETURN_IF_ERROR(createIndexQueryCtx(iqctx, qctx, groupNode));
}
}
Expand Down Expand Up @@ -118,6 +119,7 @@ Status IndexScanRule::createIndexQueryCtx(IndexQueryCtx& iqctx,
return Status::OK();
}

// Single ColumnHints item
Status IndexScanRule::createSingleIQC(IndexQueryCtx& iqctx,
const FilterItems& items,
graph::QueryContext* qctx,
Expand All @@ -132,6 +134,7 @@ Status IndexScanRule::createSingleIQC(IndexQueryCtx& iqctx,
return appendIQCtx(index, items, iqctx, newFilter);
}

// Multiple ColumnHints items
Status IndexScanRule::createMultipleIQC(IndexQueryCtx& iqctx,
const FilterItems& items,
graph::QueryContext* qctx,
Expand Down Expand Up @@ -237,7 +240,6 @@ inline bool verifyType(const Value& val) {
Status IndexScanRule::appendColHint(std::vector<IndexColumnHint>& hints,
const FilterItems& items,
const meta::cpp2::ColumnDef& col) const {
// CHECK(false);
IndexColumnHint hint;
std::pair<Value, bool> begin, end;
bool isRangeScan = true;
Expand Down Expand Up @@ -324,6 +326,7 @@ GraphSpaceID IndexScanRule::spaceId(const OptGroupNode* groupNode) const {
return in->space();
}

// TODO: Delete similar interfaces and get the filter from PlanNode
Expression* IndexScanRule::filterExpr(const OptGroupNode* groupNode) const {
auto in = static_cast<const IndexScan*>(groupNode->node());
const auto& qct = in->queryContext();
Expand Down
1 change: 1 addition & 0 deletions src/graph/optimizer/rule/IndexScanRule.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ using IndexItem = std::shared_ptr<meta::cpp2::IndexItem>;

class OptContext;

// Select the optimal index according to the preset filter inside [[IndexScan]]
class IndexScanRule final : public OptRule {
FRIEND_TEST(IndexScanRuleTest, BoundValueTest);
FRIEND_TEST(IndexScanRuleTest, IQCtxTest);
Expand Down
24 changes: 24 additions & 0 deletions src/graph/optimizer/rule/MergeGetNbrsAndDedupRule.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,30 @@
namespace nebula {
namespace opt {

// Merge [[Dedup]] and [[GetNeighbors]] node
// Required conditions:
// 1. Match the pattern
// Benefits:
// 1. Delete unnecessary node
//
// Tranformation:
// Before:
//
// +------+-------+
// | GetNeighbors |
// +------+-------+
// |
// +------+------+
// | Dedup |
// +------+------+
//
// After:
//
// +------+-------+
// | GetNeighbors |
// | (dedup=true) |
// +------+-------+

class MergeGetNbrsAndDedupRule final : public OptRule {
public:
const Pattern &pattern() const override;
Expand Down
27 changes: 27 additions & 0 deletions src/graph/optimizer/rule/MergeGetNbrsAndProjectRule.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,33 @@
namespace nebula {
namespace opt {

// Merge [[Project]] and [[GetNeighbors]] node
// Required conditions:
// 1. Match the pattern
// 2. The projection must project only one column which expression will be assigned to the src
// expression of GetNeighbors Benefits:
// 1. Delete unnecessary node
//
// Tranformation:
// Before:
//
// +------+-------+
// | GetNeighbors |
// | (src:$-.vage)|
// +------+-------+
// |
// +-------+-------+
// | Project |
// |(v.age AS vage)|
// +-------+-------+
//
// After:
//
// +------+-------+
// | GetNeighbors |
// | (src:v.age) |
// +------+-------+

class MergeGetNbrsAndProjectRule final : public OptRule {
public:
const Pattern &pattern() const override;
Expand Down
24 changes: 24 additions & 0 deletions src/graph/optimizer/rule/MergeGetVerticesAndDedupRule.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,30 @@
namespace nebula {
namespace opt {

// Merge [[Dedup]] and [[GetVertices]] node
// Required conditions:
// 1. Match the pattern
// Benefits:
// 1. Delete unnecessary node
//
// Tranformation:
// Before:
//
// +------+-------+
// | GetVertices |
// +------+-------+
// |
// +------+------+
// | Dedup |
// +------+------+
//
// After:
//
// +------+-------+
// | GetVertices |
// | (dedup=true) |
// +------+-------+

class MergeGetVerticesAndDedupRule final : public OptRule {
public:
const Pattern &pattern() const override;
Expand Down
Loading

0 comments on commit 9a401f7

Please sign in to comment.