利用投影提升ClickHouse查询性能

news/2024/11/17 22:44:43/

ClickHouse中表排序键对与查询性能至关重要。本文介绍当使用非排序键作为查询条件时如何提升查询性能。通过对非排序键定义投影,然后物化排序结果,利用空间换时间策略,提升查询性能。

选择ClickHouse排序键的规则

当创建MergeTree表时,需要指定列的顺序作为排序键。排序键的顺序对查询性能影响很大,因为排序键决定需要计算的数据在磁盘上排列在一起的紧密程度。

当选择排序键时,应该遵循下面几个规则:

  • 把过滤条件中最常用的列排在最前面
  • 排序键的第一列应该为最常用的列且基数最低
  • 排序键不要超过3或4个,以为会影响插入性能

排序键举例

当查询过滤条件有多个列时,我们如何定义排序键,下面通过示例进行说明。

CREATE TABLE deleteme
(`product_id` UInt64,`client_id` UInt64
)
ENGINE = MergeTree
PARTITION BY product_id % 10
ORDER BY (product_id, client_id) AS
SELECT number % 100 product_id, number % 100 client_id
FROM numbers(100000000)

整个表占用空间较小,仅~7MB:

SELECT formatReadableSize(total_bytes)
FROM system.tables
WHERE name = 'deleteme'
FORMAT VerticalRow 1:
──────
formatReadableSize(total_bytes): 7.64 MiB

运行带product_id的查询条件,仅需要~1M行,因为表第一个排序键为product_id:

SELECT *
FROM deleteme
WHERE product_id = 10
FORMAT `Null`0 rows in set. Elapsed: 0.014 sec. Processed 1.03 million rows, 16.52 MB (72.40 million rows/s., 1.16 GB/s.)

但如果过滤条件使用client_id(第二个排序键),ClickHouse查询时间增加仅3倍,由于相同的client_id在product_id排序的磁盘上不同块中重复存在,ClickHouse需要读取和处理更多的数据来运行查询:

SELECT *
FROM deleteme
WHERE client_id = 10
FORMAT `Null`0 rows in set. Elapsed: 0.048 sec. Processed 2.97 million rows, 31.98 MB (61.42 million rows/s., 661.52 MB/s.)

利用投影提升性能

下面通过定义投影解决上面查询性能问题。投影概念很简单,即对client_id定义排序并重新排序,从而提升对client_id的查询性能。请看示例:

ALTER TABLE deletemeADD PROJECTION deleteme_by_client_id(SELECT *ORDER BY client_id)
ALTER TABLE deletemeMATERIALIZE PROJECTION deleteme_by_client_id

PROJECTION 定义了数据按client_id进行排序,当新的部分需要合并时,会以client_id为顺序组织数据。在查询时ClickHouse会透明地使用按Client_id排序的部分。

现在再次执行上节中的查询,可以看到仅读取~1M行数据:

SELECT *
FROM deleteme
WHERE client_id = 10
FORMAT `Null`Query id: 51a55fec-d526-480b-870b-424a0c6471d30 rows in set. Elapsed: 0.052 sec. Processed 1.25 million rows, 18.28 MB (24.17 million rows/s., 352.53 MB/s.)

为了确认projection对性能有提升作用,我们可以检查query_log:

SELECT projections
FROM system.query_log
WHERE (event_time > (now() - toIntervalMinute(5))) AND (query_id = '51a55fec-d526-480b-870b-424a0c6471d3')
LIMIT 1
FORMAT VerticalRow 1:
──────
projections: ['default.deleteme.deleteme_by_client_id']

当然采用投影会重复存储数据,但在一定场景中可以接受空间和时间的平衡,特别针对较小的表。

命令行查看查询性能

在命令行中执行查询,ClickHouse会自动生成查询性能统计。对于相同的查询会有多种写法,每种方式的查询性能可能有差异。通过分析性能统计,可能会发现最佳的查询方案。

我们可以使用 FORMAT Null 子句执行查询,则仅返回查询性能统计。上面的示例我们就使用了该功能。

SELECT *
FROM system.query_log
WHERE event_time > (now() - toIntervalMinute(10))
FORMAT `Null`Query id: 7a125064-5422-471c-a170-e18601b2d631Ok.0 rows in set. Elapsed: 0.019 sec. Processed 49.86 thousand rows, 1.81 MB (2.61 million rows/s., 94.45 MB/s.)

FORMAT Vertical

我们也可以使用FORMAT Vertical子句,是的查询结果按列方式排列,对于返回数据行较少,但数据列时查看数据比较方便。

SELECT * FROM table_with_a_lot_of_columns FORMAT VerticalRow 1:
────────
type:                                  QueryFinish
event_date:                            2022-09-22
event_time:                            2022-09-22 09:29:58
event_time_microseconds:               2022-09-22 09:29:58.298699
query_start_time:                      2022-09-22 09:29:58
query_start_time_microseconds:         2022-09-22 09:29:58.296902
query_duration_ms:                     1
read_rows:                             0
read_bytes:                            0
written_rows:                          60
written_bytes:                         8879
result_rows:                           0
result_bytes:                          0
memory_usage:                          4325156
current_database:                      public

总结

本文介绍了排序键对查询的作用,并通过示例对比使用projection提升查询性能,最后也提及如何在命令行下查询性能统计信息。参考文档:https://www.tinybird.co/clickhouse/knowledge-base/improve-performance-inverted-index


http://www.ppmy.cn/news/472292.html

相关文章

该如何快速创建一个成绩查询系统?

作为一名教师,我们经常需要查询学生的成绩,以便更好地评估他们的学习进度和制定更好的教学计划。然而,传统的手工查询成绩的方式非常耗时且容易出错。随着技术的发展和普及,我们可以通过快速创建一个成绩查询系统来更好地管理和查…

计算机专业实训图片,实训一图片的简单处理_计算机软件及应用_IT计算机_专业资料...

实训一图片的简单处理_计算机软件及应用_IT计算机_专业资料 (6页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 9.9 积分 一、Photoshop CS的界面组成Photoshop CS的界面主要由标题栏、菜单栏、属…

看完JDK并发包源码的这个性能问题,我惊了!

国庆的时候闲来无事,就随手写了一点之前说的比赛的代码,目标就是保住前 100 混个大赛的文化衫就行了。 现在还混在前 50 的队伍里面,稳的一比。 其实我觉得大家做柔性负载均衡那题的思路其实都不会差太多,就看谁能把关键的信息收集…

python爬虫爬取指定用户微博图片及内容,并进行微博分类及使用习惯分析,生成可视化图表...

虽然我是不用微博的,但由于某种原因,手机端的微博会时不时地推送几条我必须看的消息过来。微博被看久了,前几天又看到 语亮 - 简书 一年前的的微博爬虫,就有了对某人微博深入挖掘的想法。 之前语亮的爬虫不能抓取用户一条微博的多…

罗马音平假名中文可复制_这首歌,代表了我们的青春,你会唱吗(附op罗马音中文音译)...

《火影忍者》主题曲《青鸟》(中文-日语-罗马音-中文谐音) 如果振翅高飞 飛翔いたら hi sho u i ta ra 嘿把他一塔拉 我说过我不会回来 戻らないと言って mo do ra na i to i tsu te 摸多拉那一托一帖 目标是那 目指したのは me za shi ta no ha 灭咋西她诺哇 蔚蓝的 蔚蓝的 天空…

掌握生成对抗网络(GANs),召唤专属二次元老婆(老公)不是梦

全文共6706字,预计学习时长12分钟或更长 近日,《狮子王》热映,其逼真的外形,几乎可以以假乱真,让观众不禁大呼:awsl,这也太真实了吧! 实体模型、CGI动画、实景拍摄、VR等技术娴熟运用…

一梦江湖费六年——QQ群聊天分析

本文结构: 一、那些年我们加过的QQ群 二、数据读入和整理(一)——来自蓝翔的挖掘机 二、 数据读入和整理(二) ——你不知道的事 三、聊天宏观(1)——寤寐思服 三、聊天宏观(2&#x…

java开发微信公众号接受并回复消息[工程代码+图片全解]

写这篇博客时犹豫了好久,因为步骤太多了,上班了也没时间,但是我依然记得当时实现公众号自动回复时的场景,找个案例好 难,也没有一个完整的案例,想了想还是写出来吧,希望能让实现这功能的人少走弯路。 微信公众号平台也有自定义回复消息,比如我在公众号…