
本文字数:10377;估计阅读时间:26 分钟
作者: Tom Schreiber
本文在公众号【ClickHouseInc】首发

在实际业务场景中,如仪表板、告警监控或交互式分析,查询往往会反复使用相同的过滤条件(WHERE 条件),无论是针对静态数据,还是不断增长的数据,比如可观测性场景中的日志查询。尽管 ClickHouse 速度很快,但这些重复扫描仍然可能带来额外的计算开销,尤其是在过滤条件具有较强的筛选能力,但又无法充分利用主索引时。
为了解决这个问题,ClickHouse 25.3 引入了 查询条件缓存(query condition cache)——一种轻量级且高效利用内存的机制,用于记录哪些数据范围符合(或不符合)特定的查询条件。该缓存以数据粒度(granule)为单位运行,使 ClickHouse 在重复执行查询时能够跳过大量无关数据,即使查询结构发生变化,也能显著提升性能。
为了庆祝我们全新 JSON 类型的 GA(正式发布),我们将通过一个真实的数据集演示查询条件缓存的工作方式:一个从热门社交媒体平台 Bluesky 采集的 JSON 事件流。同时,我们还会深入解析 ClickHouse 的数据处理流程,以及查询条件缓存在其中的作用。提前透露一下,它速度快,占用空间小,而且即便是用于查找帖子中的椒盐卷饼表情符号这样的小众需求,依然表现卓越。
让我们深入了解一下吧!
初始化数据:导入 1 亿条 JSON 事件
我们首先在一台 32 核 CPU 的测试服务器上创建一个简化的表:
CREATE TABLE bluesky
(
data JSON(
kind LowCardinality(String),
time_us UInt64)
)
ORDER BY (
data.kind,
fromUnixTimestamp64Micro(data.time_us))
SETTINGS index_granularity_bytes = 0;
注意:设置 index_granularity_bytes = 0 会禁用自适应数据粒度阈值。这种配置 不适用于生产环境,本次实验仅使用该设置,以确保粒度大小固定,便于观察效果。
接下来,我们从 100 个存储在 S3 上的文件中导入 1 亿条 Bluesky 事件到表中:
INSERT INTO bluesky
SELECT *
FROM s3('https://clickhouse-public-datasets.s3.amazonaws.com/bluesky/file_{0001..0100}.json.gz', 'JSONAsObject')
SETTINGS
input_format_allow_errors_num = 100,
input_format_allow_errors_ratio = 1,
min_insert_block_size_bytes = 0,
min_insert_block_size_rows = 20_000_000;
注意:
-
input_format_allow_errors_* 选项可防止 ClickHouse 因少量 JSON 解析错误而终止执行。
-
min_insert_block_size_* 选项可加快数据导入速度并减少表数据合并的开销,但会占用更多内存。在低内存系统上,建议降低单次导入的行数阈值。
在正式介绍查询条件缓存之前,我们先简单了解一下 ClickHouse 的数据组织方式。
ClickHouse 的数据组织方式
目前,这张表包含 5 个数据分片,共计 1 亿行数据,未压缩数据大小为 36 GiB。
SELECT
count() AS parts,
formatReadableQuantity(sum(rows)) AS rows,
formatReadableSize(sum(data_uncompressed_bytes)) AS data_size
FROM system.parts
WHERE active AND (database = 'default') AND (`table` = 'bluesky');
┌─parts─┬─rows───────────┬─data_size─┐
│ 5 │ 100.00 million │ 35.87 GiB │
└───────┴────────────────┴───────────┘
在数据处理过程中,这 1 亿行数据会被划分为 粒度(granule),这是 ClickHouse 处理数据的最小单位。我们可以检查这 5 个数据分片 各自包含多少个粒度:
SELECT
part_name,
max(mark_number) AS granules
FROM mergeTreeIndex('default', 'bluesky')
GROUP BY part_name;
┌─part_name───┬─granules─┐
│ all_9_9_0 │ 1227 │
│ all_10_10_0 │ 1194 │
│ all_8_8_0 │ 1223 │
│ all

最低0.47元/天 解锁文章
1414

被折叠的 条评论
为什么被折叠?



