跳到主要内容
跳到主要内容

时间序列查询性能

在优化存储之后,下一步是提高查询性能。 本节探讨两种关键技术:优化 ORDER BY 键和使用物化视图。 我们将看到这些方法如何将查询时间从几秒减少到毫秒级。

优化 ORDER BY 键

在尝试其他优化之前,您应该优化它们的排序键,以确保 ClickHouse 产生最快的结果。 选择正确的键在很大程度上取决于您将要运行的查询。假设我们的大多数查询都是通过 projectsubproject 列进行过滤。 在这种情况下,将它们添加到排序键中是一个好主意 — 以及时间列,因为我们也会通过时间进行查询:

让我们创建另一个版本的表,其列类型与 wikistat 相同,但按 (project, subproject, time) 排序。

现在,让我们比较多个查询,以了解我们的排序键表达式对性能的重要性。请注意,我们尚未应用之前的数据类型和编解码优化,因此查询性能差异仅基于排序顺序。

查询(time)(project, subproject, time)
2.381 秒1.660 秒
2.148 秒0.058 秒
2.192 秒0.012 秒
2.968 秒0.010 秒

物化视图

另一个选项是使用物化视图来聚合和存储热门查询的结果。可以查询这些结果,而不是原始表。假设以下查询在我们的情况下经常执行:

创建物化视图

我们可以创建以下物化视图:

回填目标表

此目标表将在向 wikistat 表中插入新记录时填充,因此我们需要进行一些 回填

最简单的方法是使用 INSERT INTO SELECT 语句,直接将结果插入到物化视图的目标表 通过 视图的 SELECT 查询 (转换):

根据原始数据集的基数(我们有 10亿行!),这可能是一个内存密集的方案。或者,您可以使用一种占用最小内存的变体:

  • 创建一个 Null 表引擎的临时表
  • 将通常使用的物化视图的副本连接到该临时表
  • 使用 INSERT INTO SELECT 查询,将所有数据从原始数据集复制到该临时表
  • 删除临时表和临时物化视图。

通过这种方法,原始数据集的行以块的方式复制到临时表(该表不存储任何这些行),对于每个块的行,计算部分状态并写入目标表,这些状态在后台被逐步合并。

接下来,我们将创建一个物化视图,从 wikistat_backfill 读取并写入 wikistat_top

然后最后,我们将从初始的 wikistat 表填充 wikistat_backfill

一旦那个查询完成,我们可以删除回填表和物化视图:

现在我们可以查询物化视图,而不是原始表:

我们的性能提升非常显著。 之前计算这个查询的答案需要稍微超过 2 秒,而现在仅需 4 毫秒。