Skip to content
This repository was archived by the owner on May 9, 2024. It is now read-only.

Commit 671f8aa

Browse files
Devjiuienkovich
authored andcommitted
[Bench] Reduce input cols number for fetch
To estimate output size of result query to allocate buffer we are running `count*` before some actual queries. This estimation requires only query body argumnets without `select` arguments, so this commit changes input_cols for `count*` query. Resolves: #574 Signed-off-by: Dmitrii Makarenko <[email protected]>
1 parent a59f799 commit 671f8aa

11 files changed

+226
-112
lines changed

omniscidb/QueryEngine/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ set(query_engine_source_files
7979
QueryExecutionSequence.cpp
8080
QueryMemoryInitializer.cpp
8181
RelAlgDagBuilder.cpp
82+
RelAlgExecutionUnit.cpp
8283
RelAlgExecutor.cpp
8384
RelAlgTranslator.cpp
8485
RelAlgOptimizer.cpp

omniscidb/QueryEngine/CardinalityEstimator.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,10 @@ RelAlgExecutionUnit create_ndv_execution_unit(const RelAlgExecutionUnit& ra_exe_
100100

101101
RelAlgExecutionUnit create_count_all_execution_unit(
102102
const RelAlgExecutionUnit& ra_exe_unit,
103+
const SchemaProvider* schema_provider,
103104
hdk::ir::ExprPtr replacement_target) {
104105
return {ra_exe_unit.input_descs,
105-
ra_exe_unit.input_col_descs,
106+
schema_provider,
106107
ra_exe_unit.simple_quals,
107108
ra_exe_unit.quals,
108109
ra_exe_unit.join_quals,

omniscidb/QueryEngine/CardinalityEstimator.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ RelAlgExecutionUnit create_ndv_execution_unit(const RelAlgExecutionUnit& ra_exe_
6666

6767
RelAlgExecutionUnit create_count_all_execution_unit(
6868
const RelAlgExecutionUnit& ra_exe_unit,
69+
const SchemaProvider* schema_provider,
6970
hdk::ir::ExprPtr replacement_target);
7071

7172
ResultSetPtr reduce_estimator_results(

omniscidb/QueryEngine/Descriptors/QueryFragmentDescriptor.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,9 @@ void QueryFragmentDescriptor::buildFragmentPerKernelForTable(
151151
}
152152

153153
ExecutionKernelDescriptor execution_kernel_desc{
154-
device_id, {}, fragment.getNumTuples()};
154+
/*device_id*/ device_id,
155+
/*fragments*/ {},
156+
/*outer_tuple_count*/ fragment.getNumTuples()};
155157
if (table_desc_offset) {
156158
const auto frag_ids =
157159
executor->getTableFragmentIndices(ra_exe_unit,

omniscidb/QueryEngine/JoinFilterPushDown.cpp

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "IR/ExprCollector.h"
1919
#include "IR/ExprRewriter.h"
2020
#include "RelAlgExecutor.h"
21+
#include "Visitors/UsedInputsCollector.h"
2122

2223
namespace {
2324

@@ -27,15 +28,6 @@ class BindFilterToOutermostVisitor : public hdk::ir::ExprRewriter {
2728
}
2829
};
2930

30-
class InputColumnsCollector
31-
: public hdk::ir::ExprCollector<std::unordered_set<InputColDescriptor>,
32-
InputColumnsCollector> {
33-
protected:
34-
void visitColumnVar(const hdk::ir::ColumnVar* col_var) override {
35-
result_.insert(InputColDescriptor(col_var->columnInfo(), 0));
36-
}
37-
};
38-
3931
} // namespace
4032

4133
/**
@@ -49,7 +41,7 @@ FilterSelectivity RelAlgExecutor::getFilterSelectivity(
4941
const std::vector<hdk::ir::ExprPtr>& filter_expressions,
5042
const CompilationOptions& co,
5143
const ExecutionOptions& eo) {
52-
InputColumnsCollector input_columns_collector;
44+
UsedInputsCollector input_columns_collector;
5345
std::list<hdk::ir::ExprPtr> quals;
5446
BindFilterToOutermostVisitor bind_filter_to_outermost;
5547
for (const auto& filter_expr : filter_expressions) {
@@ -59,7 +51,8 @@ FilterSelectivity RelAlgExecutor::getFilterSelectivity(
5951
auto& input_column_descriptors = input_columns_collector.result();
6052
std::vector<InputDescriptor> input_descs;
6153
std::list<std::shared_ptr<const InputColDescriptor>> input_col_descs;
62-
for (const auto& input_col_desc : input_column_descriptors) {
54+
for (const auto& input_col_var : input_column_descriptors) {
55+
auto input_col_desc = InputColDescriptor(input_col_var.columnInfo(), 0);
6356
if (input_descs.empty()) {
6457
input_descs.push_back(input_col_desc.getScanDesc());
6558
} else {
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Copyright (C) 2023 Intel Corporation
3+
* Copyright 2017 MapD Technologies, Inc.
4+
*
5+
* SPDX-License-Identifier: Apache-2.0
6+
*/
7+
8+
#include "RelAlgExecutionUnit.h"
9+
#include "Visitors/UsedInputsCollector.h"
10+
11+
void RelAlgExecutionUnit::calcInputColDescs(const SchemaProvider* schema_provider) {
12+
// Scan all currently used expressions to determine used columns.
13+
UsedInputsCollector collector;
14+
for (auto& expr : simple_quals) {
15+
collector.visit(expr.get());
16+
}
17+
for (auto& expr : quals) {
18+
collector.visit(expr.get());
19+
}
20+
for (auto& expr : groupby_exprs) {
21+
if (expr) {
22+
collector.visit(expr.get());
23+
}
24+
}
25+
for (auto& join_qual : join_quals) {
26+
for (auto& expr : join_qual.quals) {
27+
collector.visit(expr.get());
28+
}
29+
}
30+
31+
for (auto& expr : target_exprs) {
32+
collector.visit(expr);
33+
}
34+
35+
if (partition_offsets_col) {
36+
collector.visit(partition_offsets_col.get());
37+
}
38+
39+
std::vector<std::shared_ptr<const InputColDescriptor>> col_descs;
40+
for (auto& col_var : collector.result()) {
41+
col_descs.push_back(std::make_shared<const InputColDescriptor>(col_var.columnInfo(),
42+
col_var.rteIdx()));
43+
}
44+
45+
// For UNION we only have column variables for a single table used
46+
// in target expressions but should mark all columns as used.
47+
if (union_all && !col_descs.empty()) {
48+
CHECK_EQ(col_descs.front()->getNestLevel(), 0);
49+
CHECK_EQ(input_descs.size(), (size_t)2);
50+
TableRef processed_table_ref(col_descs.front()->getDatabaseId(),
51+
col_descs.front()->getTableId());
52+
for (auto tdesc : input_descs) {
53+
if (tdesc.getTableRef() != processed_table_ref) {
54+
auto columns = schema_provider->listColumns(tdesc.getTableRef());
55+
for (auto& col_info : columns) {
56+
if (!col_info->is_rowid) {
57+
col_descs.push_back(std::make_shared<InputColDescriptor>(col_info, 0));
58+
}
59+
}
60+
}
61+
}
62+
}
63+
64+
std::sort(
65+
col_descs.begin(),
66+
col_descs.end(),
67+
[](std::shared_ptr<const InputColDescriptor> const& lhs,
68+
std::shared_ptr<const InputColDescriptor> const& rhs) {
69+
return std::make_tuple(lhs->getNestLevel(), lhs->getColId(), lhs->getTableId()) <
70+
std::make_tuple(rhs->getNestLevel(), rhs->getColId(), rhs->getTableId());
71+
});
72+
73+
input_col_descs.clear();
74+
input_col_descs.insert(input_col_descs.end(), col_descs.begin(), col_descs.end());
75+
}

omniscidb/QueryEngine/RelAlgExecutionUnit.h

Lines changed: 93 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/*
2+
* Copyright 2023 Intel Corporation
23
* Copyright 2017 MapD Technologies, Inc.
34
*
45
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,8 +24,7 @@
2324
* Copyright (c) 2016 MapD Technologies, Inc. All rights reserved.
2425
**/
2526

26-
#ifndef QUERYENGINE_RELALGEXECUTIONUNIT_H
27-
#define QUERYENGINE_RELALGEXECUTIONUNIT_H
27+
#pragma once
2828

2929
#include "CostModel/CostModel.h"
3030
#include "Descriptors/InputDescriptors.h"
@@ -64,14 +64,15 @@ using QueryPlanHash = size_t;
6464
// used to detect a correct cached hashtable
6565
struct HashTableBuildDag {
6666
public:
67-
HashTableBuildDag(const JoinColumnsInfo& in_inner_cols_info,
68-
const JoinColumnsInfo& in_outer_cols_info,
69-
const QueryPlan& in_inner_cols_access_path,
70-
const QueryPlan& in_outer_cols_access_path)
67+
explicit HashTableBuildDag(const JoinColumnsInfo& in_inner_cols_info,
68+
const JoinColumnsInfo& in_outer_cols_info,
69+
const QueryPlan& in_inner_cols_access_path,
70+
const QueryPlan& in_outer_cols_access_path)
7171
: inner_cols_info(in_inner_cols_info)
7272
, outer_cols_info(in_outer_cols_info)
7373
, inner_cols_access_path(in_inner_cols_access_path)
7474
, outer_cols_access_path(in_outer_cols_access_path) {}
75+
7576
JoinColumnsInfo inner_cols_info;
7677
JoinColumnsInfo outer_cols_info;
7778
QueryPlan inner_cols_access_path;
@@ -127,7 +128,88 @@ struct JoinCondition {
127128

128129
using JoinQualsPerNestingLevel = std::vector<JoinCondition>;
129130

130-
struct RelAlgExecutionUnit {
131+
class RelAlgExecutionUnit {
132+
public:
133+
RelAlgExecutionUnit(
134+
std::vector<InputDescriptor> input_descs,
135+
std::list<std::shared_ptr<const InputColDescriptor>> input_col_descs,
136+
std::list<hdk::ir::ExprPtr> simple_quals,
137+
std::list<hdk::ir::ExprPtr> quals,
138+
const JoinQualsPerNestingLevel join_quals,
139+
std::list<hdk::ir::ExprPtr> groupby_exprs,
140+
std::vector<const hdk::ir::Expr*> target_exprs,
141+
const std::shared_ptr<hdk::ir::Estimator> estimator,
142+
const SortInfo sort_info,
143+
size_t scan_limit,
144+
QueryPlan query_plan_dag = {EMPTY_QUERY_PLAN},
145+
HashTableBuildDagMap hash_table_build_plan_dag = {},
146+
TableIdToNodeMap table_id_to_node_map = {},
147+
const std::optional<bool> union_all = {},
148+
std::optional<hdk::ir::ShuffleFunction> shuffle_fn = {},
149+
hdk::ir::ExprPtr partition_offsets_col = nullptr,
150+
bool partitioned_aggregation = false,
151+
std::shared_ptr<costmodel::CostModel> cost_model = nullptr,
152+
std::vector<costmodel::AnalyticalTemplate> templs = {})
153+
: input_descs(std::move(input_descs))
154+
, input_col_descs(std::move(input_col_descs))
155+
, simple_quals(std::move(simple_quals))
156+
, quals(std::move(quals))
157+
, join_quals(std::move(join_quals))
158+
, groupby_exprs(std::move(groupby_exprs))
159+
, target_exprs(std::move(target_exprs))
160+
, estimator(std::move(estimator))
161+
, sort_info(std::move(sort_info))
162+
, scan_limit(scan_limit)
163+
, query_plan_dag(std::move(query_plan_dag))
164+
, hash_table_build_plan_dag(std::move(hash_table_build_plan_dag))
165+
, table_id_to_node_map(std::move(table_id_to_node_map))
166+
, union_all(union_all)
167+
, shuffle_fn(std::move(shuffle_fn))
168+
, partition_offsets_col(std::move(partition_offsets_col))
169+
, partitioned_aggregation(partitioned_aggregation)
170+
, cost_model(std::move(cost_model))
171+
, templs(std::move(templs)) {}
172+
173+
RelAlgExecutionUnit(std::vector<InputDescriptor> input_descs,
174+
const SchemaProvider* schema_provider,
175+
std::list<hdk::ir::ExprPtr> simple_quals,
176+
std::list<hdk::ir::ExprPtr> quals,
177+
const JoinQualsPerNestingLevel join_quals,
178+
std::list<hdk::ir::ExprPtr> groupby_exprs,
179+
std::vector<const hdk::ir::Expr*> target_exprs,
180+
const std::shared_ptr<hdk::ir::Estimator> estimator,
181+
const SortInfo sort_info,
182+
size_t scan_limit,
183+
QueryPlan query_plan_dag = {EMPTY_QUERY_PLAN},
184+
HashTableBuildDagMap hash_table_build_plan_dag = {},
185+
TableIdToNodeMap table_id_to_node_map = {},
186+
const std::optional<bool> union_all = {},
187+
std::optional<hdk::ir::ShuffleFunction> shuffle_fn = {},
188+
hdk::ir::ExprPtr partition_offsets_col = nullptr,
189+
bool partitioned_aggregation = false,
190+
std::shared_ptr<costmodel::CostModel> cost_model = nullptr,
191+
std::vector<costmodel::AnalyticalTemplate> templs = {})
192+
: input_descs(std::move(input_descs))
193+
, simple_quals(std::move(simple_quals))
194+
, quals(std::move(quals))
195+
, join_quals(std::move(join_quals))
196+
, groupby_exprs(std::move(groupby_exprs))
197+
, target_exprs(std::move(target_exprs))
198+
, estimator(std::move(estimator))
199+
, sort_info(std::move(sort_info))
200+
, scan_limit(scan_limit)
201+
, query_plan_dag(std::move(query_plan_dag))
202+
, hash_table_build_plan_dag(std::move(hash_table_build_plan_dag))
203+
, table_id_to_node_map(std::move(table_id_to_node_map))
204+
, union_all(union_all)
205+
, shuffle_fn(std::move(shuffle_fn))
206+
, partition_offsets_col(std::move(partition_offsets_col))
207+
, partitioned_aggregation(partitioned_aggregation)
208+
, cost_model(std::move(cost_model))
209+
, templs(std::move(templs)) {
210+
calcInputColDescs(schema_provider);
211+
}
212+
131213
std::vector<InputDescriptor> input_descs;
132214
std::list<std::shared_ptr<const InputColDescriptor>> input_col_descs;
133215
std::list<hdk::ir::ExprPtr> simple_quals;
@@ -158,9 +240,11 @@ struct RelAlgExecutionUnit {
158240

159241
bool isShuffleCount() const { return shuffle_fn && !partition_offsets_col; }
160242
bool isShuffle() const { return shuffle_fn && partition_offsets_col; }
243+
244+
private:
245+
// Method used for creation input_col_descs from qualifires and expressions
246+
void calcInputColDescs(const SchemaProvider* schema_provider);
161247
};
162248

163249
std::ostream& operator<<(std::ostream& os, const RelAlgExecutionUnit& ra_exe_unit);
164250
std::string ra_exec_unit_desc_for_caching(const RelAlgExecutionUnit& ra_exe_unit);
165-
166-
#endif // QUERYENGINE_RELALGEXECUTIONUNIT_H

omniscidb/QueryEngine/RelAlgExecutor.cpp

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -473,20 +473,6 @@ void RelAlgExecutor::handleNop(RaExecutionDesc& ed) {
473473

474474
namespace {
475475

476-
struct ColumnRefHash {
477-
size_t operator()(const hdk::ir::ColumnRef& col_ref) const { return col_ref.hash(); }
478-
};
479-
480-
using ColumnRefSet = std::unordered_set<hdk::ir::ColumnRef, ColumnRefHash>;
481-
482-
class UsedInputsCollector
483-
: public hdk::ir::ExprCollector<ColumnRefSet, UsedInputsCollector> {
484-
protected:
485-
void visitColumnRef(const hdk::ir::ColumnRef* col_ref) override {
486-
result_.insert(*col_ref);
487-
}
488-
};
489-
490476
const hdk::ir::Node* get_data_sink(const hdk::ir::Node* ra_node) {
491477
if (auto join = dynamic_cast<const hdk::ir::Join*>(ra_node)) {
492478
CHECK_EQ(size_t(2), join->inputCount());
@@ -1526,8 +1512,8 @@ std::optional<size_t> RelAlgExecutor::getFilteredCountAll(const WorkUnit& work_u
15261512
count_all_agg = builder.count();
15271513
}
15281514

1529-
const auto count_all_exe_unit =
1530-
create_count_all_execution_unit(work_unit.exe_unit, count_all_agg.expr());
1515+
const auto count_all_exe_unit = create_count_all_execution_unit(
1516+
work_unit.exe_unit, schema_provider_.get(), count_all_agg.expr());
15311517
size_t one{1};
15321518
hdk::ResultSetTable count_all_result;
15331519
try {
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright (C) 2023 Intel Corporation
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#pragma once
8+
9+
#include "IR/ExprCollector.h"
10+
11+
#include <unordered_set>
12+
13+
struct ColumnVarHash {
14+
size_t operator()(const hdk::ir::ColumnVar& col_var) const { return col_var.hash(); }
15+
};
16+
17+
using ColumnVarSet = std::unordered_set<hdk::ir::ColumnVar, ColumnVarHash>;
18+
19+
class UsedInputsCollector
20+
: public hdk::ir::ExprCollector<ColumnVarSet, UsedInputsCollector> {
21+
protected:
22+
void visitColumnRef(const hdk::ir::ColumnRef* col_ref) override { CHECK(false); }
23+
24+
void visitColumnVar(const hdk::ir::ColumnVar* col_var) override {
25+
result_.insert(*col_var);
26+
}
27+
};

0 commit comments

Comments
 (0)