mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-24 02:30:51 +00:00
implement ORDER BY optimization for some other meta-storages
This commit is contained in:
parent
fd5b23730e
commit
6834fbf03d
@ -27,7 +27,7 @@ ReadInOrderOptimizer::ReadInOrderOptimizer(
|
||||
forbidden_columns.insert(elem.first);
|
||||
}
|
||||
|
||||
InputSortingInfoPtr ReadInOrderOptimizer::analyze(const StoragePtr & storage)
|
||||
InputSortingInfoPtr ReadInOrderOptimizer::analyze(const StoragePtr & storage) const
|
||||
{
|
||||
const MergeTreeData * merge_tree = dynamic_cast<const MergeTreeData *>(storage.get());
|
||||
if (!merge_tree || !merge_tree->hasSortingKey())
|
||||
@ -51,10 +51,6 @@ InputSortingInfoPtr ReadInOrderOptimizer::analyze(const StoragePtr & storage)
|
||||
order_key_prefix_descr.push_back(required_sort_description[i]);
|
||||
else
|
||||
{
|
||||
const auto & input_columns = elements_actions[i]->getRequiredColumnsWithTypes();
|
||||
if (input_columns.size() != 1 || input_columns.front().name != sorting_key_columns[i])
|
||||
break;
|
||||
|
||||
bool first = true;
|
||||
for (const auto & action : elements_actions[i]->getActions())
|
||||
{
|
||||
@ -69,6 +65,12 @@ InputSortingInfoPtr ReadInOrderOptimizer::analyze(const StoragePtr & storage)
|
||||
else
|
||||
first = false;
|
||||
|
||||
if (action.argument_names.size() != 1 || action.argument_names.at(0) != sorting_key_columns[i])
|
||||
{
|
||||
current_direction = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
const auto & func = *action.function_base;
|
||||
if (!func.hasInformationAboutMonotonicity())
|
||||
{
|
||||
@ -76,7 +78,7 @@ InputSortingInfoPtr ReadInOrderOptimizer::analyze(const StoragePtr & storage)
|
||||
break;
|
||||
}
|
||||
|
||||
auto monotonicity = func.getMonotonicityForRange(*input_columns.front().type, {}, {});
|
||||
auto monotonicity = func.getMonotonicityForRange(*func.getArgumentTypes().at(0), {}, {});
|
||||
if (!monotonicity.is_monotonic)
|
||||
{
|
||||
current_direction = 0;
|
||||
|
@ -20,7 +20,7 @@ public:
|
||||
const SortDescription & required_sort_description,
|
||||
const SyntaxAnalyzerResultPtr & syntax_result);
|
||||
|
||||
InputSortingInfoPtr analyze(const StoragePtr & storage);
|
||||
InputSortingInfoPtr analyze(const StoragePtr & storage) const;
|
||||
|
||||
private:
|
||||
ManyExpressionActions elements_actions;
|
||||
|
@ -58,7 +58,7 @@ struct SyntaxAnalyzerResult;
|
||||
using SyntaxAnalyzerResultPtr = std::shared_ptr<const SyntaxAnalyzerResult>;
|
||||
|
||||
class ReadInOrderOptimizer;
|
||||
using ReadInOrderOptimizerPtr = std::shared_ptr<ReadInOrderOptimizer>;
|
||||
using ReadInOrderOptimizerPtr = std::shared_ptr<const ReadInOrderOptimizer>;
|
||||
|
||||
/** Query along with some additional data,
|
||||
* that can be used during query processing
|
||||
@ -72,9 +72,9 @@ struct SelectQueryInfo
|
||||
|
||||
PrewhereInfoPtr prewhere_info;
|
||||
|
||||
InputSortingInfoPtr input_sorting_info;
|
||||
|
||||
ReadInOrderOptimizerPtr order_by_optimizer;
|
||||
/// We can modify it while reading from storage
|
||||
mutable InputSortingInfoPtr input_sorting_info;
|
||||
|
||||
/// Prepared sets are used for indices by storage engine.
|
||||
/// Example: x IN (1, 2, 3)
|
||||
|
@ -165,6 +165,9 @@ BlockInputStreams StorageBuffer::read(
|
||||
|
||||
if (dst_has_same_structure)
|
||||
{
|
||||
if (query_info.order_by_optimizer)
|
||||
query_info.input_sorting_info = query_info.order_by_optimizer->analyze(destination);
|
||||
|
||||
/// The destination table has the same structure of the requested columns and we can simply read blocks from there.
|
||||
streams_from_dst = destination->read(column_names, query_info, context, processed_stage, max_block_size, num_streams);
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <DataStreams/IBlockOutputStream.h>
|
||||
|
||||
#include <Storages/StorageFactory.h>
|
||||
#include <Storages/ReadInOrderOptimizer.h>
|
||||
|
||||
#include <Common/typeid_cast.h>
|
||||
|
||||
@ -200,6 +201,9 @@ BlockInputStreams StorageMaterializedView::read(
|
||||
{
|
||||
auto storage = getTargetTable();
|
||||
auto lock = storage->lockStructureForShare(false, context.getCurrentQueryId());
|
||||
if (query_info.order_by_optimizer)
|
||||
query_info.input_sorting_info = query_info.order_by_optimizer->analyze(storage);
|
||||
|
||||
auto streams = storage->read(column_names, query_info, context, processed_stage, max_block_size, num_streams);
|
||||
for (auto & stream : streams)
|
||||
stream->addTableLock(lock);
|
||||
|
@ -217,15 +217,14 @@ BlockInputStreams StorageMerge::read(
|
||||
auto current_info = query_info.order_by_optimizer->analyze(it->first);
|
||||
if (it == selected_tables.begin())
|
||||
input_sorting_info = current_info;
|
||||
else if (!current_info || *current_info != *input_sorting_info)
|
||||
else if (!current_info || (input_sorting_info && *current_info != *input_sorting_info))
|
||||
input_sorting_info.reset();
|
||||
|
||||
if (!input_sorting_info)
|
||||
break;
|
||||
}
|
||||
|
||||
/// We have to modify query_info to create proper pipeline after read stage.
|
||||
const_cast<SelectQueryInfo &>(query_info).input_sorting_info = input_sorting_info;
|
||||
query_info.input_sorting_info = input_sorting_info;
|
||||
}
|
||||
|
||||
for (auto it = selected_tables.begin(); it != selected_tables.end(); ++it)
|
||||
|
Loading…
Reference in New Issue
Block a user