allow to move more conditions to PREWHERE

This commit is contained in:
Anton Popov 2021-04-21 01:01:24 +03:00
parent a25e6d96a5
commit a83a07246e
3 changed files with 65 additions and 8 deletions

View File

@ -218,14 +218,20 @@ void MergeTreeWhereOptimizer::optimize(ASTSelectQuery & select) const
if (!it->viable)
break;
/// 10% ratio is just a guess.
/// If sizes of compressed columns cannot be calculated, e.g. for compact parts,
/// use number of moved columns as a fallback.
bool moved_enough =
(total_size_of_queried_columns > 0 && total_size_of_moved_conditions > 0
&& (total_size_of_moved_conditions + it->columns_size) * 10 > total_size_of_queried_columns)
|| (total_number_of_moved_columns > 0
&& (total_number_of_moved_columns + it->identifiers.size()) * 10 > queried_columns.size());
bool moved_enough = false;
if (total_size_of_queried_columns > 0)
{
/// If we know size of queried columns use it as threshold. 10% ratio is just a guess.
moved_enough = total_size_of_moved_conditions > 0
&& (total_size_of_moved_conditions + it->columns_size) * 10 > total_size_of_queried_columns;
}
else
{
/// Otherwise, use number of moved columns as a fallback.
/// It can happen, if table has only compact parts. 25% ratio is just a guess.
moved_enough = total_number_of_moved_columns > 0
&& (total_number_of_moved_columns + it->identifiers.size()) * 4 > queried_columns.size();
}
if (moved_enough)
break;

View File

@ -0,0 +1,14 @@
1 Wide
2 Compact
35
SELECT count()
FROM t_move_to_prewhere
PREWHERE a AND b AND c
WHERE (a AND b AND c) AND (NOT ignore(fat_string))
1 Compact
2 Compact
35
SELECT count()
FROM t_move_to_prewhere
PREWHERE a
WHERE a AND (b AND c AND (NOT ignore(fat_string)))

View File

@ -0,0 +1,37 @@
DROP TABLE IF EXISTS t_move_to_prewhere;
CREATE TABLE t_move_to_prewhere (id UInt32, a UInt8, b UInt8, c UInt8, fat_string String)
ENGINE = MergeTree ORDER BY id PARTITION BY id
SETTINGS min_rows_for_wide_part = 100, min_bytes_for_wide_part = 0;
INSERT INTO t_move_to_prewhere SELECT 1, number % 2 = 0, number % 3 = 0, number % 5 = 0, repeat('a', 1000) FROM numbers(1000);
INSERT INTO t_move_to_prewhere SELECT 2, number % 2 = 0, number % 3 = 0, number % 5 = 0, repeat('a', 1000) FROM numbers(10);
SELECT partition, part_type FROM system.parts
WHERE table = 't_move_to_prewhere' AND database = currentDatabase()
ORDER BY partition;
SELECT count() FROM t_move_to_prewhere WHERE a AND b AND c AND NOT ignore(fat_string);
EXPLAIN SYNTAX SELECT count() FROM t_move_to_prewhere WHERE a AND b AND c AND NOT ignore(fat_string);
DROP TABLE IF EXISTS t_move_to_prewhere;
-- With only compact parts, we cannot move 3 conditions to PREWHERE,
-- because we don't know sizes and we can use only number of columns in conditions.
-- Sometimes moving a lot of columns to prewhere may be harmful.
CREATE TABLE t_move_to_prewhere (id UInt32, a UInt8, b UInt8, c UInt8, fat_string String)
ENGINE = MergeTree ORDER BY id PARTITION BY id
SETTINGS min_rows_for_wide_part = 10000, min_bytes_for_wide_part = 100000000;
INSERT INTO t_move_to_prewhere SELECT 1, number % 2 = 0, number % 3 = 0, number % 5 = 0, repeat('a', 1000) FROM numbers(1000);
INSERT INTO t_move_to_prewhere SELECT 2, number % 2 = 0, number % 3 = 0, number % 5 = 0, repeat('a', 1000) FROM numbers(10);
SELECT partition, part_type FROM system.parts
WHERE table = 't_move_to_prewhere' AND database = currentDatabase()
ORDER BY partition;
SELECT count() FROM t_move_to_prewhere WHERE a AND b AND c AND NOT ignore(fat_string);
EXPLAIN SYNTAX SELECT count() FROM t_move_to_prewhere WHERE a AND b AND c AND NOT ignore(fat_string);
DROP TABLE IF EXISTS t_move_to_prewhere;