新年快乐!同时,ClickHouse 也迎来了新的版本发布。我们很高兴推出 23.x 系列的第一个版本 23.1。
像往常一样,我们举办了 ClickHouse 社区电话会议,讨论了版本发布,提供了现场演示,并回答了大家的问题。
敬请期待 23.2 版本网络研讨会的发布公告。此外,如果您想了解更多关于 ClickHouse 基础知识的信息,请查看即将举行的培训课程
版本摘要
- 新增 17 个功能。
- 性能优化 17 项。
- 修复了 78 个错误。
当然,还有大量的性能改进。
如果这些还不足以引起您尝试它的兴趣。请查看一些重点内容
倒排全文索引 - Larry Luo,Harry Lee
没错,您没看错。在这个版本中,我们添加了对 ClickHouse 中倒排索引作为数据跳过索引的实验性支持。虽然这并没有使 ClickHouse 成为一个功能齐全的搜索引擎,但它为提高特定基于标记的查询的性能引入了一些有趣的可能性。如果您有一个包含大量文本 Blob 的数据集,并且您在上面执行标记匹配,那么此功能适合您。
此索引可用于加速执行标记匹配的任何字符串函数,特别是 multiSearchAny 和 hasToken 函数。这应该允许您构建如下所示的相当复杂的布尔条件。此外,等式运算符(如 LIKE
、IN
和 ==
)都从中受益,例如:
SELECT * from tab WHERE s == 'Hello World';
SELECT * from tab WHERE s IN ('Hello', 'World');
SELECT * from tab WHERE s LIKE '%Hello%';
演示此功能的最简单方法是使用包含大量文本的数据集。还有什么比我们最喜欢的 Hacker News 数据更好呢?
考虑一下我们 play.clickhouse.com 环境中的此查询,它查找一段时间内提及 ClickHouse 的所有帖子
SELECT toYYYYMM(toDateTime(time)) AS monthYear, bar(count(), 0, 120, 20) AS count FROM hackernews WHERE (text ILIKE '%ClickHouse%') GROUP BY monthYear ORDER BY monthYear ASC │ 201910 │ ▊ │ │ 201911 │ ██▊ │ │ 201912 │ █▎ │ │ 202001 │ ███████████▏ │ │ 202002 │ ██████ │ │ 202003 │ ███████████▌ │ │ 202004 │ ███████▏ │ │ 202005 │ █████▋ │ │ 202006 │ █████▊ │ │ 202007 │ ███████▎ │ │ 202008 │ ███▌ │ │ 202009 │ ██▊ │ │ 202010 │ ████▌ │ │ 202011 │ ████▋ │ │ 202012 │ ███▏ │ │ 202101 │ ██▊ │ │ 202102 │ ████████▎ │ │ 202103 │ ████████████▏ │ │ 202104 │ ██▌ │ │ 202105 │ ████████████▏ │ │ 202106 │ ██▏ │ │ 202107 │ ████▏ │ │ 202108 │ ████ │ │ 202109 │ ████████████████▎ │ │ 202110 │ ████████████████████ │ │ 202111 │ ███████████▌ │ │ 202112 │ ███████████▏ │ │ 202201 │ ██████▊ │ │ 202202 │ ███████ │ │ 202203 │ ████▊ │ │ 202204 │ █████████▋ │ │ 202205 │ █████████████ │ │ 202206 │ █████████████▊ │ │ 202207 │ ████████████▌ │ │ 202208 │ ██████▊ │ │ 202209 │ █████████▊ │ │ 202210 │ ████████████████████ │ │ 202211 │ ██████▏ │ │ 202212 │ █▋ │ └───────────┴──────────────────────┘ 67 rows in set. Elapsed: 0.561 sec. Processed 33.95 million rows, 11.62 GB (60.53 million rows/s., 20.72 GB/s.) ✎
除了我们变得越来越有新闻价值之外,请注意这里的时间安排。尽管速度很快,但就其当前形式而言,此查询需要对整个文档集进行线性扫描。我们可以使用跳过索引的常规语法将倒排索引添加到文本和标题字段
ALTER TABLE hackernews ADD INDEX inv_idx(text) TYPE inverted;
ALTER TABLE hackernews MATERIALIZE INDEX inv_idx;
SELECT toYYYYMM(toDateTime(time)) AS monthYear, bar(count(), 0, 120, 20) AS count FROM hackernews_indexed WHERE multiSearchAny(text, ['ClickHouse', 'Clickhouse', 'clickHouse', 'clickhouse']) GROUP BY monthYear ORDER BY monthYear ASC │ 202210 │ ████████████████████ │ │ 202211 │ ██████▏ │ │ 202212 │ █▋ │ └───────────┴──────────────────────┘ 72 rows in set. Elapsed: 0.285 sec. Processed 6.07 million rows, 2.18 GB (21.27 million rows/s., 7.65 GB/s.) ✎
要检查索引是否正在使用,可以在查询前面加上 EXPLAIN indexes=
,例如:
EXPLAIN indexes = 1 SELECT toYYYYMM(toDateTime(time)) AS monthYear, bar(count(), 0, 120, 20) AS count FROM hackernews_indexed WHERE text LIKE '%clickhouse%' GROUP BY monthYear ORDER BY monthYear ASC ┌─explain──────────────────────────────────────────────────────┐ │ Expression ((Projection + Before ORDER BY [lifted up part])) │ │ Sorting (Sorting for ORDER BY) │ │ Expression (Before ORDER BY) │ │ Aggregating │ │ Expression (Before GROUP BY) │ │ ReadFromMergeTree (default.hackernews_indexed) │ │ Indexes: │ │ PrimaryKey │ │ Condition: true │ │ Parts: 1/1 │ │ Granules: 4150/4150 │ │ Skip │ │ Name: inv_idx │ │ Description: inverted GRANULARITY 1 │ │ Parts: 1/1 │ │ Granules: 4150/4150 │ └──────────────────────────────────────────────────────────────┘ ✎
一些限制(毕竟它是实验性的)
- 我们不会在帖子中存储术语的位置,从而阻止短语匹配或优化 multisearchallpositions 等函数。
- 我们没有相关性计算 - 为此,我们需要持久化术语统计信息,这在初始迭代中被认为超出范围。目前,索引仅用于加速匹配。
- 文本通过在空格处拆分或通过 可配置的 n 元组大小(如果您需要子字符串匹配)进行标记化。文本处理不可配置,因此此功能不可与 Lucene 等自然语言引擎相比。
总而言之,如果您需要加速简单的标记匹配,那么此功能适合您。“日志数据怎么样?”您可能会问,也许?我们将在后续文章中作为我们 可观察性系列 的一部分进行讨论。
如果您需要相关性功能和更细致的文本匹配(例如电子商务),也许暂时不要替换您的搜索引擎……但请继续关注;我们预计将在未来版本中看到此功能的改进,并且 ClickHouse 的发展速度很快 :)
我们预计你们中的许多人会对如何实现此功能提出疑问。敬请期待很快发布的关于内部机制的后续博客。
参数化视图 - Smita Kulkarni
任何编写大量 SQL 的人都很快就会学会欣赏视图。它们允许用户抽象掉复杂的查询并以表语法的形式公开它们 - 允许从组件部分构建更复杂的查询,而不会被大量的 SQL 代码淹没。到目前为止,用户只能创建静态视图。随着 ClickHouse 23.1 版本的发布,我们可以根据查询时传递的参数创建动态视图。
假设我们想要一个用于搜索 Stack Overflow 数据集的视图。此数据集可在 [https://archive.org/details/stackexchange] 上找到,并且 此处描述为帖子。
下面的示例是静态的,仅限于搜索 ClickHouse
帖子。
CREATE VIEW search_clickhouse_stackoverflow AS SELECT Id, CreationDate, Title, LastActivityDate, ViewCount, AnswerCount, Score FROM stackoverflow WHERE (PostTypeId = 1) AND multiSearchAny(Body, ['ClickHouse']) SELECT * FROM search_clickhouse_stackoverflow LIMIT 1 FORMAT Vertical Row 1: ────── Id: 71655910 CreationDate: 2022-03-29 02:50:35.920000000 Title: How to execute "with" query locally in ClickHouse? LastActivityDate: 2022-03-29 03:08:04.863000000 ViewCount: 48 AnswerCount: 0 Score: 0 1 row in set. Elapsed: 1.445 sec. Processed 200.26 thousand rows, 276.42 MB (138.60 thousand rows/s., 191.31 MB/s.) ✎
理想情况下,我们希望此视图比仅搜索 ClickHouse 帖子更灵活。使用参数化视图,我们现在可以概括此视图
CREATE VIEW search_stackoverflow AS SELECT Id, CreationDate, Title, LastActivityDate, ViewCount, AnswerCount, Score FROM stackoverflow WHERE (PostTypeId = 1) AND multiSearchAny(Body, splitByWhitespace({text:String})) SELECT * FROM search_stackoverflow(text = 'ClickHouse MergeTree') ORDER BY Score DESC LIMIT 1 FORMAT Vertical Row 1: ────── Id: 40592010 CreationDate: 2016-11-14 15:13:55.310000000 Title: Multiple small inserts in clickhouse LastActivityDate: 2021-01-06 09:14:48.947000000 ViewCount: 15849 AnswerCount: 5 Score: 15 1 row in set. Elapsed: 0.594 sec. Processed 5.79 million rows, 8.10 GB (9.75 million rows/s., 13.62 GB/s.) ✎
请注意,我们还在空格处拆分查询字符串以利用 multiSearchAny
函数。我们还使用倒排索引进行优化。这代表了一种粗略的搜索功能,但希望可以让您了解如何组合这些功能。
查询结果缓存 - Robert Schutze,Mikhail Stetsyuk
为了获得最大性能,分析型数据库会优化其内部数据存储和处理管道的每个步骤。但是,数据库执行的最佳工作是根本不执行任何工作!缓存是一种特别流行的技术,通过存储先前计算的结果或远程数据(访问成本很高)来避免不必要的工作。ClickHouse 广泛使用缓存,例如,缓存 DNS 记录、本地和远程 (S3) 数据、推断的模式、编译的查询和正则表达式。在 23.1 中,我们为 ClickHouse 缓存家族引入了新成员,即查询结果缓存!
查询缓存基于这样一个理念,即有时在缓存昂贵的 SELECT 查询的结果是可以接受的,以便可以从缓存中直接提供相同查询的后续执行。根据查询类型,这可以显着降低 ClickHouse 服务器的延迟和资源消耗。例如,考虑像 Grafana 或 Apache Superset 这样的数据可视化工具,它显示过去 24 小时的汇总销售额报告。在大多数情况下,一天内的销售额变化会比较缓慢,我们可以(例如)每三个小时才刷新一次报告。从 ClickHouse v23.1 开始,SELECT 查询可以提供一个“生存时间”,在此期间服务器只会计算查询的第一次执行,而后续执行则无需进一步计算,可以直接从缓存中获取答案。
用户应注意,这不是一个事务一致的缓存 - 如果基础数据发生变化,则不会从缓存中删除条目。这是设计使然,并且由于多种原因是合理的。作为 OLAP 数据库,我们容忍略有不准确的结果,以换取性能和缓存可扩展性。ClickHouse 还具有后台操作,例如可能更改数据的合并折叠,这将使事务一致的缓存可能无效。因此,缓存条目仅基于 TTL,之后其条目将被删除。
由于这是一个如此重要的功能,并且有很多可调设置,我们很快就会发布一篇关于此功能的专门博文。