dbms: improvement [#METR-15484].

This commit is contained in:
Alexey Milovidov 2015-03-27 06:37:46 +03:00
parent cfc5b313cc
commit 06c35e0faa
4 changed files with 37 additions and 35 deletions

View File

@ -293,7 +293,7 @@ public:
*/
void execute(Block & block, const ColumnNumbers & arguments, size_t result, bool negative) const;
std::string describe()
std::string describe() const
{
if (!ordered_set_elements)
return "{}";
@ -312,7 +312,7 @@ public:
}
/// проверяет есть ли в Set элементы для заданного диапазона индекса
BoolMask mayBeTrueInRange(const Range & range);
BoolMask mayBeTrueInRange(const Range & range) const;
size_t getTotalRowCount() const { return data.getTotalRowCount(); }
size_t getTotalByteCount() const { return data.getTotalByteCount(); }

View File

@ -280,20 +280,20 @@ public:
/// Выполнимо ли условие в диапазоне ключей.
/// left_pk и right_pk должны содержать все поля из sort_descr в соответствующем порядке.
bool mayBeTrueInRange(const Field * left_pk, const Field * right_pk);
bool mayBeTrueInRange(const Field * left_pk, const Field * right_pk) const;
/// Выполнимо ли условие в полубесконечном (не ограниченном справа) диапазоне ключей.
/// left_pk должен содержать все поля из sort_descr в соответствующем порядке.
bool mayBeTrueAfter(const Field * left_pk);
bool mayBeTrueAfter(const Field * left_pk) const;
/// Проверяет, что индекс не может быть использован.
bool alwaysUnknown();
bool alwaysUnknown() const;
/// Наложить дополнительное условие: значение в столбце column должно быть в диапазоне range.
/// Возвращает, есть ли такой столбец в первичном ключе.
bool addCondition(const String & column, const Range & range);
String toString();
String toString() const;
private:
/// Выражение хранится в виде обратной польской строки (Reverse Polish Notation).
struct RPNElement
@ -318,7 +318,7 @@ private:
RPNElement(Function function_, size_t key_column_, const Range & range_)
: function(function_), range(range_), key_column(key_column_) {}
String toString();
String toString() const;
Function function;
@ -328,13 +328,13 @@ private:
/// Для FUNCTION_IN_SET
ASTPtr in_function;
ASTSet * inFunctionToSet();
const ASTSet * inFunctionToSet() const;
};
typedef std::vector<RPNElement> RPN;
typedef std::map<String, size_t> ColumnIndices;
bool mayBeTrueInRange(const Field * left_pk, const Field * right_pk, bool right_bounded);
bool mayBeTrueInRange(const Field * left_pk, const Field * right_pk, bool right_bounded) const;
void traverseAST(ASTPtr & node, Block & block_with_constants);
bool atomFromAST(ASTPtr & node, Block & block_with_constants, RPNElement & out);

View File

@ -558,7 +558,7 @@ void Set::executeArray(const ColumnArray * key_column, ColumnUInt8::Container_t
}
BoolMask Set::mayBeTrueInRange(const Range & range)
BoolMask Set::mayBeTrueInRange(const Range & range) const
{
if (!ordered_set_elements)
throw DB::Exception("Ordered set in not created.");
@ -588,7 +588,10 @@ BoolMask Set::mayBeTrueInRange(const Range & range)
}
else
{
auto left_it = range.left_bounded ? std::lower_bound(ordered_set_elements->begin(), ordered_set_elements->end(), left) : ordered_set_elements->begin();
auto left_it = range.left_bounded
? std::lower_bound(ordered_set_elements->begin(), ordered_set_elements->end(), left)
: ordered_set_elements->begin();
if (range.left_bounded && !range.left_included && left_it != ordered_set_elements->end() && *left_it == left)
++left_it;
@ -599,7 +602,10 @@ BoolMask Set::mayBeTrueInRange(const Range & range)
}
else
{
auto right_it = range.right_bounded ? std::upper_bound(ordered_set_elements->begin(), ordered_set_elements->end(), right) : ordered_set_elements->end();
auto right_it = range.right_bounded
? std::upper_bound(ordered_set_elements->begin(), ordered_set_elements->end(), right)
: ordered_set_elements->end();
if (range.right_bounded && !range.right_included && right_it != ordered_set_elements->begin() && *(right_it--) == right)
--right_it;
@ -613,13 +619,9 @@ BoolMask Set::mayBeTrueInRange(const Range & range)
--right_it;
/// в диапазон не попадает ни одного ключа из in
if (*right_it < *left_it)
{
can_be_true = false;
}
else
{
can_be_true = true;
}
}
}
}

View File

@ -42,7 +42,7 @@ PKCondition::PKCondition(ASTPtr query, const Context & context_, const NamesAndT
if (select.prewhere_expression)
{
traverseAST(select.prewhere_expression, block_with_constants);
rpn.push_back(RPNElement(RPNElement::FUNCTION_AND));
rpn.emplace_back(RPNElement::FUNCTION_AND);
}
}
else if (select.prewhere_expression)
@ -51,7 +51,7 @@ PKCondition::PKCondition(ASTPtr query, const Context & context_, const NamesAndT
}
else
{
rpn.push_back(RPNElement(RPNElement::FUNCTION_UNKNOWN));
rpn.emplace_back(RPNElement::FUNCTION_UNKNOWN);
}
}
@ -59,8 +59,8 @@ bool PKCondition::addCondition(const String & column, const Range & range)
{
if (!pk_columns.count(column))
return false;
rpn.push_back(RPNElement(RPNElement::FUNCTION_IN_RANGE, pk_columns[column], range));
rpn.push_back(RPNElement(RPNElement::FUNCTION_AND));
rpn.emplace_back(RPNElement::FUNCTION_IN_RANGE, pk_columns[column], range);
rpn.emplace_back(RPNElement::FUNCTION_AND);
return true;
}
@ -224,7 +224,7 @@ bool PKCondition::operatorFromAST(ASTFunction * func, RPNElement & out)
return true;
}
String PKCondition::toString()
String PKCondition::toString() const
{
String res;
for (size_t i = 0; i < rpn.size(); ++i)
@ -236,7 +236,7 @@ String PKCondition::toString()
return res;
}
bool PKCondition::mayBeTrueInRange(const Field * left_pk, const Field * right_pk, bool right_bounded)
bool PKCondition::mayBeTrueInRange(const Field * left_pk, const Field * right_pk, bool right_bounded) const
{
/// Найдем диапазоны элементов ключа.
std::vector<Range> key_ranges(sort_descr.size(), Range());
@ -264,7 +264,7 @@ bool PKCondition::mayBeTrueInRange(const Field * left_pk, const Field * right_pk
std::vector<BoolMask> rpn_stack;
for (size_t i = 0; i < rpn.size(); ++i)
{
RPNElement & element = rpn[i];
const auto & element = rpn[i];
if (element.function == RPNElement::FUNCTION_UNKNOWN)
{
rpn_stack.emplace_back(true, true);
@ -281,9 +281,9 @@ bool PKCondition::mayBeTrueInRange(const Field * left_pk, const Field * right_pk
}
else if (element.function == RPNElement::FUNCTION_IN_SET || element.function == RPNElement::FUNCTION_NOT_IN_SET)
{
ASTFunction * in_func = typeid_cast<ASTFunction *>(element.in_function.get());
ASTs & args = typeid_cast<ASTExpressionList &>(*in_func->arguments).children;
ASTSet * ast_set = typeid_cast<ASTSet *>(args[1].get());
auto in_func = typeid_cast<const ASTFunction *>(element.in_function.get());
const ASTs & args = typeid_cast<const ASTExpressionList &>(*in_func->arguments).children;
auto ast_set = typeid_cast<const ASTSet *>(args[1].get());
if (in_func && ast_set)
{
const Range & key_range = key_ranges[element.key_column];
@ -325,27 +325,27 @@ bool PKCondition::mayBeTrueInRange(const Field * left_pk, const Field * right_pk
return rpn_stack[0].can_be_true;
}
bool PKCondition::mayBeTrueInRange(const Field * left_pk, const Field * right_pk)
bool PKCondition::mayBeTrueInRange(const Field * left_pk, const Field * right_pk) const
{
return mayBeTrueInRange(left_pk, right_pk, true);
}
bool PKCondition::mayBeTrueAfter(const Field * left_pk)
bool PKCondition::mayBeTrueAfter(const Field * left_pk) const
{
return mayBeTrueInRange(left_pk, nullptr, false);
}
ASTSet * PKCondition::RPNElement::inFunctionToSet()
const ASTSet * PKCondition::RPNElement::inFunctionToSet() const
{
ASTFunction * in_func = typeid_cast<ASTFunction *>(in_function.get());
auto in_func = typeid_cast<const ASTFunction *>(in_function.get());
if (!in_func)
return nullptr;
ASTs & args = typeid_cast<ASTExpressionList &>(*in_func->arguments).children;
ASTSet * ast_set = typeid_cast<ASTSet *>(args[1].get());
const ASTs & args = typeid_cast<const ASTExpressionList &>(*in_func->arguments).children;
auto ast_set = typeid_cast<const ASTSet *>(args[1].get());
return ast_set;
}
String PKCondition::RPNElement::toString()
String PKCondition::RPNElement::toString() const
{
std::ostringstream ss;
switch (function)
@ -376,13 +376,13 @@ String PKCondition::RPNElement::toString()
}
bool PKCondition::alwaysUnknown()
bool PKCondition::alwaysUnknown() const
{
std::vector<UInt8> rpn_stack;
for (size_t i = 0; i < rpn.size(); ++i)
{
RPNElement & element = rpn[i];
const auto & element = rpn[i];
if (element.function == RPNElement::FUNCTION_UNKNOWN)
{