Compare commits

...

5 Commits

Author SHA1 Message Date
Ivan Milinović
6e4f0dc683 Merge branch 'master' into T-fix-orderby-spike 2023-12-19 22:46:42 +01:00
Matija Pintarić
845aefc447 Merge branch 'master' into T-fix-orderby-spike 2023-11-11 22:02:13 +01:00
Matija
a2d813440a Minor change 2023-11-11 22:01:41 +01:00
Matija
2624e5d10c PR fix and add workload 2023-11-11 21:58:37 +01:00
Matija
09c333c4a1 Fix order by memory spike 2023-11-03 18:23:15 +01:00
3 changed files with 70 additions and 5 deletions

View File

@@ -75,6 +75,8 @@ jobs:
./benchmark.py vendor-native --num-workers-for-benchmark 12 --export-results cartesian.json cartesian
./benchmark.py vendor-native --num-workers-for-benchmark 12 --export-results order_by.json order_by
- name: Upload mgbench results
run: |
cd tools/bench-graph-client
@@ -104,3 +106,9 @@ jobs:
--github-run-id "${{ github.run_id }}" \
--github-run-number "${{ github.run_number }}" \
--head-branch-name "${{ env.BRANCH_NAME }}"
./main.py --benchmark-name "order_by" \
--benchmark-results "../../tests/mgbench/order_by.json" \
--github-run-id "${{ github.run_id }}" \
--github-run-number "${{ github.run_number }}" \
--head-branch-name "${{ env.BRANCH_NAME }}"

View File

@@ -238,6 +238,16 @@ std::optional<std::string> GetOptionalStringValue(query::Expression *expression,
return {};
};
bool IsOrderByQuery(const std::vector<memgraph::query::Clause *> &clauses) {
for (const auto &clause : clauses) {
if (clause->GetTypeInfo() == Return::kType) {
auto *return_clause = utils::Downcast<Return>(clause);
return !return_clause->body_.order_by.empty();
}
}
return false;
}
bool IsAllShortestPathsQuery(const std::vector<memgraph::query::Clause *> &clauses) {
for (const auto &clause : clauses) {
if (clause->GetTypeInfo() != Match::kType) {
@@ -1591,8 +1601,8 @@ PreparedQuery PrepareCypherQuery(ParsedQuery parsed_query, std::map<std::string,
}
// If this is LOAD CSV query, use PoolResource without MonotonicMemoryResource as we want to reuse allocated memory
auto use_monotonic_memory =
!contains_csv && !IsCallBatchedProcedureQuery(clauses) && !IsAllShortestPathsQuery(clauses);
auto use_monotonic_memory = !contains_csv && !IsCallBatchedProcedureQuery(clauses) &&
!IsAllShortestPathsQuery(clauses) && !IsOrderByQuery(clauses);
MG_ASSERT(current_db.execution_db_accessor_, "Cypher query expects a current DB transaction");
auto *dba =
@@ -1754,8 +1764,8 @@ PreparedQuery PrepareProfileQuery(ParsedQuery parsed_query, bool in_explicit_tra
// If this is LOAD CSV, BatchedProcedure or AllShortest query, use PoolResource without MonotonicMemoryResource as we
// want to reuse allocated memory
auto use_monotonic_memory =
!contains_csv && !IsCallBatchedProcedureQuery(clauses) && !IsAllShortestPathsQuery(clauses);
auto use_monotonic_memory = !contains_csv && !IsCallBatchedProcedureQuery(clauses) &&
!IsAllShortestPathsQuery(clauses) && !IsOrderByQuery(clauses);
MG_ASSERT(cypher_query, "Cypher grammar should not allow other queries in PROFILE");
EvaluationContext evaluation_context;
@@ -3716,7 +3726,8 @@ Interpreter::PrepareResult Interpreter::Prepare(const std::string &query_string,
auto const &clauses = cypher_query->single_query_->clauses_;
bool hasAllShortestPaths = IsAllShortestPathsQuery(clauses);
// Using PoolResource without MonotonicMemoryResouce for LOAD CSV reduces memory usage.
bool usePool = hasAllShortestPaths || IsCallBatchedProcedureQuery(clauses) || IsLoadCsvQuery(clauses);
bool usePool = hasAllShortestPaths || IsCallBatchedProcedureQuery(clauses) || IsLoadCsvQuery(clauses) ||
IsOrderByQuery(clauses);
return {usePool, hasAllShortestPaths};
}(); // IILE

View File

@@ -0,0 +1,46 @@
# Copyright 2023 Memgraph Ltd.
#
# Use of this software is governed by the Business Source License
# included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
# License, and you may not use this file except in compliance with the Business Source License.
#
# As of the Change Date specified in that file, in accordance with
# the Business Source License, use of this software will be governed
# by the Apache License, Version 2.0, included in the file
# licenses/APL.txt.
from workloads.base import Workload
class OrderBy(Workload):
NAME = "order_by"
CARDINALITY = 10000
def indexes_generator(self):
return [
("CREATE INDEX ON :Node;", {}),
("CREATE INDEX ON :Node(prop1);", {}),
("CREATE INDEX ON :Node(prop2);", {}),
("CREATE INDEX ON :Node(prop3);", {}),
]
def dataset_generator(self):
queries = []
for i in range(0, OrderBy.CARDINALITY):
queries.append(
(
"""CREATE
(:Node {prop1: $id, prop2: $id, prop3: $id
});
""",
{"id": i},
)
)
return queries
def benchmark__test__order_by(self):
return (
"MATCH (n:Node) RETURN n ORDER BY n.prop1",
{},
)