mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 15:12:02 +00:00
dbms: removing duplicate elements from ORDER BY [#METR-2944].
This commit is contained in:
parent
ed0bb6f3da
commit
db2956eb73
@ -218,6 +218,9 @@ private:
|
|||||||
/// Eliminates injective function calls and constant expressions from group by statement
|
/// Eliminates injective function calls and constant expressions from group by statement
|
||||||
void optimizeGroupBy();
|
void optimizeGroupBy();
|
||||||
|
|
||||||
|
/// Удалить из ORDER BY повторяющиеся элементы.
|
||||||
|
void optimizeOrderBy();
|
||||||
|
|
||||||
/// Превратить перечисление значений или подзапрос в ASTSet. node - функция in или notIn.
|
/// Превратить перечисление значений или подзапрос в ASTSet. node - функция in или notIn.
|
||||||
void makeSet(ASTFunction * node, const Block & sample_block);
|
void makeSet(ASTFunction * node, const Block & sample_block);
|
||||||
|
|
||||||
|
@ -85,6 +85,9 @@ void ExpressionAnalyzer::init()
|
|||||||
/// GROUP BY injective function elimination.
|
/// GROUP BY injective function elimination.
|
||||||
optimizeGroupBy();
|
optimizeGroupBy();
|
||||||
|
|
||||||
|
/// Удалить из ORDER BY повторяющиеся элементы.
|
||||||
|
optimizeOrderBy();
|
||||||
|
|
||||||
/// array_join_alias_to_name, array_join_result_to_source.
|
/// array_join_alias_to_name, array_join_result_to_source.
|
||||||
getArrayJoinedColumns();
|
getArrayJoinedColumns();
|
||||||
|
|
||||||
@ -531,6 +534,38 @@ void ExpressionAnalyzer::optimizeGroupBy()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ExpressionAnalyzer::optimizeOrderBy()
|
||||||
|
{
|
||||||
|
if (!(select_query && select_query->order_expression_list))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/// Уникализируем условия сортировки.
|
||||||
|
using NameAndLocale = std::pair<std::string, std::string>;
|
||||||
|
std::set<NameAndLocale> elems_set;
|
||||||
|
|
||||||
|
ASTs & elems = select_query->order_expression_list->children;
|
||||||
|
ASTs unique_elems;
|
||||||
|
unique_elems.reserve(elems.size());
|
||||||
|
|
||||||
|
for (const auto & elem : elems)
|
||||||
|
{
|
||||||
|
String name = elem->children.front()->getColumnName();
|
||||||
|
const ASTOrderByElement & order_by_elem = typeid_cast<const ASTOrderByElement &>(*elem);
|
||||||
|
|
||||||
|
if (elems_set.emplace(
|
||||||
|
std::piecewise_construct,
|
||||||
|
std::forward_as_tuple(name),
|
||||||
|
std::forward_as_tuple(order_by_elem.collator ? order_by_elem.collator->getLocale() : std::string())).second)
|
||||||
|
{
|
||||||
|
unique_elems.emplace_back(elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unique_elems.size() < elems.size())
|
||||||
|
elems = unique_elems;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ExpressionAnalyzer::makeSetsForIndex()
|
void ExpressionAnalyzer::makeSetsForIndex()
|
||||||
{
|
{
|
||||||
if (storage && ast && storage->supportsIndexForIn())
|
if (storage && ast && storage->supportsIndexForIn())
|
||||||
|
@ -817,12 +817,10 @@ static SortDescription getSortDescription(ASTSelectQuery & query)
|
|||||||
{
|
{
|
||||||
SortDescription order_descr;
|
SortDescription order_descr;
|
||||||
order_descr.reserve(query.order_expression_list->children.size());
|
order_descr.reserve(query.order_expression_list->children.size());
|
||||||
for (ASTs::iterator it = query.order_expression_list->children.begin();
|
for (const auto & elem : query.order_expression_list->children)
|
||||||
it != query.order_expression_list->children.end();
|
|
||||||
++it)
|
|
||||||
{
|
{
|
||||||
String name = (*it)->children.front()->getColumnName();
|
String name = elem->children.front()->getColumnName();
|
||||||
const ASTOrderByElement & order_by_elem = typeid_cast<const ASTOrderByElement &>(**it);
|
const ASTOrderByElement & order_by_elem = typeid_cast<const ASTOrderByElement &>(*elem);
|
||||||
|
|
||||||
order_descr.emplace_back(name, order_by_elem.direction, order_by_elem.collator);
|
order_descr.emplace_back(name, order_by_elem.direction, order_by_elem.collator);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
SELECT n FROM (SELECT number AS n FROM system.numbers LIMIT 1000000) ORDER BY n, n, n, n, n, n, n, n, n, n LIMIT 1000000, 1;
|
Loading…
Reference in New Issue
Block a user