TABLE default.OriginalMetrics (`appId` UInt32, `metricId` UInt32, `timestamp` UInt32, `value` Float64, `tags.name` Array(UInt32), `tags.value` Array(UInt32), `savedTimestamp` UInt32 DEFAULT toUInt32(now()) CODEC(DoubleDelta)) ENGINE = ReplicatedMergeTree('/clickhouse/tables/metrics/shard1/OriginalMetrics', 'replica1') PARTITION BY floor(timestamp / 86400) ORDER BY (appId, metricId, timestamp) SETTINGS index_granularity = 8192;
Эти значения UInt32 но в другой подсистеме есть маппинг String -> UInt32 (вместо строк в КХ храним инты для экономии места и скорости запросов)
metricId UInt32
tags.name Array(UInt32)
tags.value Array(UInt32)
2. CREATE TABLE default.MetricsLowCardinality (`appId` UInt32, `metricId` LowCardinality(String), `timestamp` UInt32, `value` Float64, `tags.name` Array(LowCardinality(String)), `tags.value` Array(LowCardinality(String)), `savedTimestamp` UInt32 DEFAULT toUInt32(now()) CODEC(DoubleDelta)) ENGINE = ReplicatedMergeTree('/clickhouse/tables/metrics/shard1/MetricsLowCardinality', 'replica1') PARTITION BY floor(timestamp / 86400) ORDER BY (appId, metricId, timestamp) SETTINGS index_granularity = 8192;
Решили попробовать без нашего внешнего маппинга
metricId LowCardinality(String)
tags.name Array(LowCardinality(String))
tags.value Array(LowCardinality(String)),
Что получилось?
1. По месту на диске с LowCardinality есть даже выигрыш в 8-10%, круто.
2. А вот по скорости запросов просадка в 2 раза где-то.
Запросы вида
Наш маппинг
select * from OriginalMetrics where tags.value[indexOf(tags.name, 3)]=4 or tags.value[indexOf(tags.name, 25)]=6 or tags.value[indexOf(tags.name, 6)]=7 or tags.value[indexOf(tags.name, 7)]=8 or tags.value[indexOf(tags.name, 8)]=9;
localhost:9000, queries 8159, QPS: 195.443, RPS: 27743076.974, MiB/s: 1147.484, result RPS: 0.000, result MiB/s: 0.000.
LowCardinality
select * from MetricsLowCardinality where tags.value[indexOf(tags.name, '3')]='4' or tags.value[indexOf(tags.name, '25')]='6' or tags.value[indexOf(tags.name,' 6')]='7' or tags.value[indexOf(tags.name, '7')]='8' or tags.value[indexOf(tags.name, '8')]='9';
localhost:9000, queries 7874, QPS: 90.795, RPS: 10249710.351, MiB/s: 225.113, result RPS: 0.000, result MiB/s: 0.000.
Как я понимаю LowCardinality внитри работает как и наш маппинг, где-то внутри партиции храниться словарь
Почему работает в 2 раза медленнее? Может материализация Стринги происходит перед выполнением where? В некоторых случаях наверное можно этого избежать?
Как ускорить? Или скорости которая у нас с нашим маппингом все равно не достичь?
Есть у кого-нибудь объяснение? Или лучше в Гите опрос задать?
Ну потому, что словарь на каждый парт и тд свой
Обсуждают сегодня