Clickhouse:如何在 Clickhouse 中使用“Data Skipping Indexes”和“Manipulations With Data Skipping Indices”功能?

Clickhouse: how to use `Data Skipping Indexes` and `Manipulations With Data Skipping Indices` features in clickhouse?

我正在使用 Clickhouse 中的 Data Skipping Indexes 功能,但我对它的用法感到困惑。如果我在创建 table 时添加数据跳过索引,如下所示:

CREATE TABLE MyTable
(
    ...
    INDEX index_time TimeStamp TYPE minmax GRANULARITY 1
)
ENGINE =MergeTree()
...

当我使用 TimeStamp 过滤条件进行查询时,'index_time' 有效。但是,如果我在创建 table 时没有添加索引,或者,我添加了具有 Manipulations With Data Skipping Indices 特征的索引,如下所示:

ALTER TABLEE MyTable ADD INDEX index_time TimeStamp TYPE minmax GRANULARITY 1

那么索引'index_time'就不起作用了。

我的数据库 运行 正在生产中,所以我无法重新创建 table。我必须使用第二种方式。谁能解释为什么它不起作用或我以错误的方式使用该功能?

您的查询在 ALTER TABLE ADD INDEX 之后不使用索引的原因是索引尚不存在。 (!)

任何新数据都将被正确索引,这就是为什么当您将索引放入 CREATE TABLE 时索引会起作用。 ClickHouse 在您加载数据时构建索引。如果您创建了 table、运行 ALTER TABLE ADD INDEX,并加载了数据,您会看到相同的行为。

当数据已经存在时,情况就不一样了。 ALTER TABLE 更新 table 的元数据,但此时您的所有数据都已写入 table 中的部分。 ClickHouse 不会自动重写部分来实现新的索引。但是,您应该能够通过 运行:

强制重写以包含索引
OPTIMIZE TABLE MyTable FINAL 

有关详细信息,请参阅 Ruijang 引用的 Github 问题 https://github.com/yandex/ClickHouse/issues/6561

说的很对

OPTIMIZE TABLE my_table_name FINAL;

会重新创建设置为 table 的索引。但是在列式数据库中的某些情况下,您希望避免重写所有内容。如果您只是在重建包含两个步骤的新索引时将单个索引添加到已经存在的包含大量数据的 table:

步骤 1 - 定义索引

创建 INDEX 本身只是定义索引应该做什么,这在 Clickhouse 中反映为添加到 table 的元数据。因此实际上没有建立索引,因此没有什么会更快。它也是一个轻量级操作,因为它不会更改数据或在 table 元数据旁边构建任何结构。

重要的是要了解任何新传入的数据都将在插入时编制索引,但不包括任何先前存在的数据!

ALTER TABLE my_table_name ADD INDEX my_index(my_expression) TYPE minmax GRANULARITY 1

注意 Clickhouse 可以索引表达式,因此它可以只是问题中的列名或更复杂的表达式(例如 my_index(price * sold_items * revshare))。当然,该索引仅适用于该表达式。

第 2 步 - 建立(具体化)索引

创建元数据后,需要为现有数据建立索引。此操作称为 materialize,需要明确触发。好处是您可以为添加或更改的任何索引单独执行此操作。这是一项繁重的操作,因为它会触发数据库工作。

ALTER TABLE my_table_name MATERIALIZE INDEX my_index;

另请查看 Manipulating Data Skipping Indices

的 Clickhouse 文档