ClickHouse 的 Skip Indexes(跳跃索引)如何理解?
1 个回答
在自己的世界独善其身在别人的世界顺其自然。小青ClickHouse 的 **Skip Indexes(跳跃索引)** 是一种提高数据查询性能的索引机制,主要用于快速过滤掉大量不相关的数据,以减少扫描的数据量,从而提升查询性能。以下详细说明其原理、使用场景及实践方式: ## 一、Skip Indexes 概述 **Skip Indexes** 又称为跳跃索引或数据稀疏索引,是一种允许 ClickHouse 在扫描数据时跳过不相关数据块的索引机制。不同于传统数据库索引(如 MySQL 的 B+树索引)定位到具体行,ClickHouse 的跳跃索引是一种 **粗粒度的块级索引**。 其本质: - **不是精准定位单行数据**,而是根据索引信息判断数据块内是否可能包含所需数据,从而决定是否跳过这个数据块。 - 使用跳跃索引后,查询性能提高的前提是:查询条件足够精确,并且数据块间存在明显的数据区分度。 ## 二、Skip Indexes 的实现原理 ClickHouse 数据按数据块(data part 和 granule)存储,每个数据块都会生成一个数据摘要(data summary),用于描述该数据块中某列数据的分布情况。 当查询发生时,ClickHouse 会: 1. 读取每个数据块的索引信息(索引粒度信息,granule)。 2. 根据查询条件判断某些数据块是否完全无关。 3. 若发现数据块的索引摘要表明该块不可能有满足条件的数据,则 ClickHouse 会跳过此数据块,无需扫描。 因此,这种索引又被称为『数据跳跃索引』(skip index),因为它并非用于精确定位具体的行,而是用于高效地跳过大范围不相关的数据。 ## 三、Skip Indexes 的分类及配置方法 ClickHouse 常见的几种跳跃索引类型: - **minmax (最常用)** - 存储每个数据块的最大最小值。 - 查询时通过条件比较最大最小值,判断是否跳过。 - **set** - 存储数据块内唯一值集合(哈希表)。 - 查询使用 IN 查询场景下效果明显。 - **ngrambf_v1, bloom_filter, tokenbf_v1 等布隆过滤器** - 适用于字符串模糊查询、文本检索等。 - 数据以布隆过滤器的形式存储,用于快速判断数据块是否可能存在查询数据。 ## 四、创建 Skip Index 示例 ```sql CREATE TABLE orders ( order_id UInt64, user_id UInt32, product_id UInt32, order_date Date, amount Float32 ) ENGINE = MergeTree() PARTITION BY toYYYYMM(order_date) ORDER BY (user_id, order_date) SETTINGS index_granularity = 8192, index_granularity_bytes = '10MB'; -- 创建一个跳跃索引示例(针对amount字段) ALTER TABLE orders ADD INDEX amount_idx (amount) TYPE minmax GRANULARITY 3; -- 解释: -- 在这里,我们针对 amount 字段建立了一个跳跃索引, -- ClickHouse 会每隔一定数据粒度(如每 8192 行)建立一个摘要(如最大值、最小值), -- 当我们查询类似 amount > 1000 时,会根据最大、最小值决定是否跳过数据块。 ``` ## 三、什么时候适合用跳跃索引? **适合场景:** - 数据分布存在明显聚集性或数据值范围分布较宽。 - 查询条件经常使用范围查询(>, <, between)。 - 数据分布不均匀,且索引列常用于过滤。 例如: - 日期字段(如 order_date)适合 Skip Index,因为数据通常连续且区分度高。 - 用户 ID 或金额范围查询也适合,因为这些字段经常用范围条件筛选。 反之,类似 UUID、随机值、区分度低的字段,不适合建立跳跃索引。 ## 四、如何合理评估跳跃索引的效果? Skip Index 并非万能索引,不会总是提高性能。要发挥其优势,需考虑: - 数据的排序(ORDER BY)和分区策略是否合理。 - 数据块内数据的区分度足够高,以便索引能够有效跳过无用块。 - 查询场景中是否有频繁的范围或精确值过滤。 ## 四、跳跃索引使用示例 以实际场景解释: 假设有大量订单数据,数据以月份分区、user_id排序,数据量为数亿行。 用户查询最近一个月内 user_id=123 的订单记录: ```sql SELECT * FROM orders WHERE user_id = 123456 AND order_date BETWEEN '2024-01-01' AND '2024-01-31'; ``` 若未用跳跃索引: - ClickHouse 会扫描整个月份所有的数据。 若启用了跳跃索引(如 set 或 minmax): - ClickHouse 在每个数据块摘要中,快速判断 user_id 是否可能存在,不存在则跳过整个数据块。 - 数据量越大、跳过比例越高,性能提升越明显。 ## 五、跳跃索引的注意事项 - 跳跃索引会稍微增加数据存储空间(但通常很小,开销不明显)。 - 建议只在确定查询场景明确、索引区分度高的字段上建立跳跃索引。 - 跳跃索引并不总是加快查询(索引本身也有构建和存储成本),所以需根据具体场景测试性能后决定是否启用。 ## 五、如何创建跳跃索引 创建方法如下: ```sql ALTER TABLE table_name ADD INDEX idx_name (column_name) TYPE minmax GRANULARITY 8192; ``` - `index_granularity` 参数控制数据块摘要间隔大小(8192行为默认)。 - 可通过如下方式查询是否有效: ```sql SELECT * FROM system.data_skipping_indices WHERE table = 'your_table'; ``` ## 总结 ClickHouse 跳跃索引(Skip Indexes)本质是数据块级别的稀疏索引,利用块级摘要实现高效的粗粒度数据过滤,在大数据查询场景下能显著减少 I/O 和提升性能。但需要合理设计索引,确保在适当的字段上使用,才能真正发挥效果。发布于 2025-03-07 00:01 •IP属地 宁夏举报评论收藏
公众号进入网站体验更佳

