6

Data Skipping Indexes在 clickhouse 中使用该功能,但我对它的用法感到困惑。如果我在创建这样的表时添加数据跳过索引:

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

当我使用TimeStamp过滤条件查询时,“index_time”有效。但是,如果我在创建表时没有添加索引,或者,我添加了具有Manipulations With Data Skipping Indices如下功能的索引:

ALTER TABLEE MyTable ADD INDEX index_time TimeStamp TYPE minmax GRANULARITY 1

然后索引'index_time'不起作用。

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

4

2 回答 2

6

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

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

当数据已经存在时,情况就不同了。ALTER TABLE 更新表的元数据,但此时您的所有数据都已写入表中的各个部分。ClickHouse 不会自动重写部件以实现新索引。但是,您应该能够通过运行强制重写以包含索引:

OPTIMIZE TABLE MyTable FINAL 

更多信息参见瑞江引用的 Github issue https://github.com/yandex/ClickHouse/issues/6561 。

于 2019-09-03T05:43:58.657 回答
0

这是完全正确的

OPTIMIZE TABLE my_table_name FINAL;

确实重新创建了为表设置的索引。但是在柱状数据库中有一些场景,您希望避免重写所有内容。如果您只是在重建新索引时将单个索引添加到包含大量数据的现有表中,其中包括两个步骤:

第 1 步 - 定义索引

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

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

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;

还可以查看 Clickhouse docs for Manipulating Data Skipping Indices

于 2022-01-19T10:49:46.463 回答