Setting move to prewhere if final

This commit is contained in:
kssenii 2021-07-03 11:28:24 +00:00
parent edce77803f
commit a9a91a4f15
5 changed files with 70 additions and 2 deletions

View File

@ -93,6 +93,7 @@ class IColumn;
M(Bool, distributed_directory_monitor_split_batch_on_failure, false, "Should StorageDistributed DirectoryMonitors try to split batch into smaller in case of failures.", 0) \
\
M(Bool, optimize_move_to_prewhere, true, "Allows disabling WHERE to PREWHERE optimization in SELECT queries from MergeTree.", 0) \
M(Bool, optimize_move_to_prewhere_if_final, false, "If query has `final`, optimization `move_to_prewhere` is enabled only if `optimize_move_to_prewhere` and `optimize_move_to_prewhere_if_final` are enabled", 0) \
\
M(UInt64, replication_alter_partitions_sync, 1, "Wait for actions to manipulate the partitions. 0 - do not wait, 1 - wait for execution only of itself, 2 - wait for everyone.", 0) \
M(UInt64, replication_alter_columns_timeout, 60, "Wait for actions to change the table structure within the specified number of seconds. 0 - wait unlimited time.", 0) \

View File

@ -506,7 +506,7 @@ InterpreterSelectQuery::InterpreterSelectQuery(
result_header = getSampleBlockImpl();
};
analyze(settings.optimize_move_to_prewhere);
analyze(settings.optimize_move_to_prewhere && moveToPrewhereIfFinal());
bool need_analyze_again = false;
if (analysis_result.prewhere_constant_filter_description.always_false || analysis_result.prewhere_constant_filter_description.always_true)
@ -1532,6 +1532,13 @@ void InterpreterSelectQuery::addEmptySourceToQueryPlan(
}
}
bool InterpreterSelectQuery::moveToPrewhereIfFinal()
{
const Settings & settings = context->getSettingsRef();
const ASTSelectQuery & query = getSelectQuery();
return !query.final() || settings.optimize_move_to_prewhere_if_final;
}
void InterpreterSelectQuery::addPrewhereAliasActions()
{
const Settings & settings = context->getSettingsRef();
@ -1541,7 +1548,7 @@ void InterpreterSelectQuery::addPrewhereAliasActions()
if (!expressions.prewhere_info)
{
const bool does_storage_support_prewhere = !input && !input_pipe && storage && storage->supportsPrewhere();
if (does_storage_support_prewhere && settings.optimize_move_to_prewhere)
if (does_storage_support_prewhere && settings.optimize_move_to_prewhere && moveToPrewhereIfFinal())
{
/// Execute row level filter in prewhere as a part of "move to prewhere" optimization.
expressions.prewhere_info = std::make_shared<PrewhereInfo>(

View File

@ -118,6 +118,7 @@ private:
ASTSelectQuery & getSelectQuery() { return query_ptr->as<ASTSelectQuery &>(); }
void addPrewhereAliasActions();
bool moveToPrewhereIfFinal();
Block getSampleBlockImpl();

View File

@ -1,9 +1,12 @@
optimize_move_to_prewhere_if_final = 1
SELECT
x,
y,
z
FROM prewhere_move_select_final
PREWHERE y > 100
SELECT
x,
y,
@ -11,6 +14,7 @@ SELECT
FROM prewhere_move_select_final
FINAL
PREWHERE y > 100
SELECT
x,
y,
@ -18,6 +22,7 @@ SELECT
FROM prewhere_move_select_final
FINAL
WHERE z > 400
SELECT
x,
y,
@ -26,3 +31,36 @@ FROM prewhere_move_select_final
FINAL
PREWHERE y > 100
WHERE (y > 100) AND (z > 400)
optimize_move_to_prewhere_if_final = 0
SELECT
x,
y,
z
FROM prewhere_move_select_final
PREWHERE y > 100
SELECT
x,
y,
z
FROM prewhere_move_select_final
FINAL
WHERE y > 100
SELECT
x,
y,
z
FROM prewhere_move_select_final
FINAL
WHERE z > 400
SELECT
x,
y,
z
FROM prewhere_move_select_final
FINAL
WHERE (y > 100) AND (z > 400)

View File

@ -1,15 +1,36 @@
DROP TABLE IF EXISTS prewhere_move_select_final;
CREATE TABLE prewhere_move_select_final (x Int, y Int, z Int) ENGINE = ReplacingMergeTree() ORDER BY (x, y);
INSERT INTO prewhere_move_select_final SELECT number, number * 2, number * 3 FROM numbers(1000);
select 'optimize_move_to_prewhere_if_final = 1';
SET optimize_move_to_prewhere_if_final = 1;
-- order key can be pushed down with final
select '';
EXPLAIN SYNTAX SELECT * FROM prewhere_move_select_final WHERE y > 100;
select '';
EXPLAIN SYNTAX SELECT * FROM prewhere_move_select_final FINAL WHERE y > 100;
-- can not be pushed down
select '';
EXPLAIN SYNTAX SELECT * FROM prewhere_move_select_final FINAL WHERE z > 400;
-- only y can be pushed down
select '';
EXPLAIN SYNTAX SELECT * FROM prewhere_move_select_final FINAL WHERE y > 100 and z > 400;
select '';
select 'optimize_move_to_prewhere_if_final = 0';
SET optimize_move_to_prewhere_if_final = 0;
select '';
EXPLAIN SYNTAX SELECT * FROM prewhere_move_select_final WHERE y > 100;
select '';
EXPLAIN SYNTAX SELECT * FROM prewhere_move_select_final FINAL WHERE y > 100;
select '';
EXPLAIN SYNTAX SELECT * FROM prewhere_move_select_final FINAL WHERE z > 400;
select '';
EXPLAIN SYNTAX SELECT * FROM prewhere_move_select_final FINAL WHERE y > 100 and z > 400;
DROP TABLE prewhere_move_select_final;