Merge pull request #71866 from ClickHouse/fix_index_load_for_limit_1

Do not load indexes if key condition in not useful
This commit is contained in:
Alexander Gololobov 2024-11-14 11:58:24 +00:00 committed by GitHub
commit 6e864958f9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 60 additions and 13 deletions

View File

@ -1045,7 +1045,6 @@ MarkRanges MergeTreeDataSelectExecutor::markRangesFromPKRange(
MarkRanges res;
size_t marks_count = part->index_granularity.getMarksCount();
const auto & index = part->getIndex();
if (marks_count == 0)
return res;
@ -1073,6 +1072,10 @@ MarkRanges MergeTreeDataSelectExecutor::markRangesFromPKRange(
auto index_columns = std::make_shared<ColumnsWithTypeAndName>();
const auto & key_indices = key_condition.getKeyIndices();
DataTypes key_types;
if (!key_indices.empty())
{
const auto & index = part->getIndex();
for (size_t i : key_indices)
{
if (i < index->size())
@ -1082,6 +1085,7 @@ MarkRanges MergeTreeDataSelectExecutor::markRangesFromPKRange(
key_types.emplace_back(primary_key.data_types[i]);
}
}
/// If there are no monotonic functions, there is no need to save block reference.
/// Passing explicit field to FieldRef allows to optimize ranges and shows better performance.

View File

@ -1,4 +1,18 @@
100000000 100000000
0 0
Row 1:
──────
round(primary_key_bytes_in_memory, -7): 100000000 -- 100.00 million
round(primary_key_bytes_in_memory_allocated, -7): 100000000 -- 100.00 million
Row 1:
──────
primary_key_bytes_in_memory: 0
primary_key_bytes_in_memory_allocated: 0
1
100000000 100000000
Row 1:
──────
primary_key_bytes_in_memory: 0
primary_key_bytes_in_memory_allocated: 0
1
Row 1:
──────
round(primary_key_bytes_in_memory, -7): 100000000 -- 100.00 million
round(primary_key_bytes_in_memory_allocated, -7): 100000000 -- 100.00 million

View File

@ -3,17 +3,26 @@ CREATE TABLE test (s String) ENGINE = MergeTree ORDER BY s SETTINGS index_granul
SET optimize_trivial_insert_select = 1;
INSERT INTO test SELECT randomString(1000) FROM numbers(100000);
SELECT round(primary_key_bytes_in_memory, -7), round(primary_key_bytes_in_memory_allocated, -7) FROM system.parts WHERE database = currentDatabase() AND table = 'test';
SELECT round(primary_key_bytes_in_memory, -7), round(primary_key_bytes_in_memory_allocated, -7) FROM system.parts WHERE database = currentDatabase() AND table = 'test' FORMAT Vertical;
DETACH TABLE test;
SET max_memory_usage = '50M';
ATTACH TABLE test;
SELECT primary_key_bytes_in_memory, primary_key_bytes_in_memory_allocated FROM system.parts WHERE database = currentDatabase() AND table = 'test';
SELECT primary_key_bytes_in_memory, primary_key_bytes_in_memory_allocated FROM system.parts WHERE database = currentDatabase() AND table = 'test' FORMAT Vertical;
SET max_memory_usage = '200M';
-- Run a query that doesn use indexes
SELECT s != '' FROM test LIMIT 1;
SELECT round(primary_key_bytes_in_memory, -7), round(primary_key_bytes_in_memory_allocated, -7) FROM system.parts WHERE database = currentDatabase() AND table = 'test';
-- Check that index was not loaded
SELECT primary_key_bytes_in_memory, primary_key_bytes_in_memory_allocated FROM system.parts WHERE database = currentDatabase() AND table = 'test' FORMAT Vertical;
-- Run a query that uses PK index
SELECT s != '' FROM test WHERE s < '9999999999' LIMIT 1;
-- Check that index was loaded
SELECT round(primary_key_bytes_in_memory, -7), round(primary_key_bytes_in_memory_allocated, -7) FROM system.parts WHERE database = currentDatabase() AND table = 'test' FORMAT Vertical;
DROP TABLE test;

View File

@ -5,9 +5,19 @@
100000000 100000000
0 0
0 0
Query that does not use index for table `test`
1
0 0
0 0
Query that uses index in for table `test`
1
100000000 100000000
0 0
Query that does not use index for table `test2`
1
100000000 100000000
0 0
Query that uses index for table `test2`
1
100000000 100000000
100000000 100000000

View File

@ -16,8 +16,18 @@ SELECT round(primary_key_bytes_in_memory, -7), round(primary_key_bytes_in_memory
SYSTEM UNLOAD PRIMARY KEY {CLICKHOUSE_DATABASE:Identifier}.test2;
SELECT round(primary_key_bytes_in_memory, -7), round(primary_key_bytes_in_memory_allocated, -7) FROM system.parts WHERE database = currentDatabase() AND table IN ('test', 'test2');
SELECT 'Query that does not use index for table `test`';
SELECT s != '' FROM test LIMIT 1;
SELECT round(primary_key_bytes_in_memory, -7), round(primary_key_bytes_in_memory_allocated, -7) FROM system.parts WHERE database = currentDatabase() AND table IN ('test', 'test2');
SELECT 'Query that uses index in for table `test`';
SELECT s != '' FROM test WHERE s < '99999999' LIMIT 1;
SELECT round(primary_key_bytes_in_memory, -7), round(primary_key_bytes_in_memory_allocated, -7) FROM system.parts WHERE database = currentDatabase() AND table IN ('test', 'test2');
SELECT 'Query that does not use index for table `test2`';
SELECT s != '' FROM test2 LIMIT 1;
SELECT round(primary_key_bytes_in_memory, -7), round(primary_key_bytes_in_memory_allocated, -7) FROM system.parts WHERE database = currentDatabase() AND table IN ('test', 'test2');
SELECT 'Query that uses index for table `test2`';
SELECT s != '' FROM test2 WHERE s < '99999999' LIMIT 1;
SELECT round(primary_key_bytes_in_memory, -7), round(primary_key_bytes_in_memory_allocated, -7) FROM system.parts WHERE database = currentDatabase() AND table IN ('test', 'test2');