在ClickHouse中使用聚合组合器

ClickHouse 聚合函数 ClickHouse 聚合函数 本贴最后更新于783天前,其中的信息可能已经水流花落 背景 ClickHouse 中内置许多标准 SQL 外的函数。 这里记录一下其中聚合函数的学习笔记。 聚合函数 常用函数 count 返回记录条数。 如 SELECT count() FROM table 注:如果求COUNT(DISTINCT x),则使用uniq函数 ... 阅读详情

图片

本文字数:10477;估计阅读时间:27 分钟

审校:大平

图片

Meetup活动

ClickHouse Shenzhen User Group第1届 Meetup 火热报名中,详见文末海报!

ClickHouse不仅支持标准聚合函数,还支持许多更高级的函数,以涵盖大多数分析用例。除了聚合函数外,ClickHouse还提供了聚合组合器,这是查询功能的强大扩展,可以满足大量需求。

组合器允许扩展和混合聚合,以解决各种数据结构的需求。这种能力使我们能够调整查询而不是表,甚至回答最复杂的问题。

在这篇博文中,我们将探讨聚合组合器,如何用它简化查询,同时避免对数据进行结构性更改的需要。

如何使用组合器

要使用组合器,我们必须做两件事。首先,选择考虑使用的聚合函数;假设我们想使用sum()函数。其次,选择案例所需的组合器;假设需要一个If组合器。要在查询中使用 if ,我们就要将将组合器添加到函数名中:

SELECT sumIf(...)

更有用的特性是,我们甚至可以在一个函数中:组合任意数量的组合器:

SELECT sumArrayIf(...)

在这里,我们将sum()函数与Array和If组合器组合在一起:

图片

这个特定的例子说明:允许有条件地对数组列的内容进行求和。

让我们探讨一些可以使用组合器的实际案例。

在聚合中的增加条件

我们有时需要根据特定条件对数据进行聚合。我们就可以使用If组合器,并将条件指定为组合函数的最后一个参数,而不是使用WHERE子句:

图片

假设我们有一个用户付款表,结构如下(使用示例数据填充):

CREATE TABLE payments
(
    `total_amount` Float,
    `status` ENUM('declined', 'confirmed'),
    `create_time` DateTime,
    `confirm_time` DateTime
)
ENGINE = MergeTree
ORDER BY (status, create_time)

假设我们想获得总金额,但仅当付款被确认时,即 status="confirmed":

SELECT sumIf(total_amount, status = 'confirmed') FROM payments

┌─sumIf(total_amount, equals(status, 'declined'))─┐
│                               10780.18000793457 │
└─────────────────────────────────────────────────┘

我们可以使用与WHERE子句相同的语法来使用条件。让我们获取确认付款的总金额,但当confirm_time比create_time晚1分钟时:

SELECT sumIf(total_amount, (status = 'confirmed') AND (confirm_time > (create_time + toIntervalMinute(1)))) AS confirmed_and_checked
FROM payments

┌─confirmed_and_checked─┐
│     11195.98991394043 │
└───────────────────────┘

使用条件If相对于标准WHERE子句的主要优势在于能够为不同的子句计算多个总和。我们还可以在组合函数中使用任何可用的聚合函数,如countIf()、avgIf()或quantileIf() - 任何函数。结合这些功能,我们可以在单个请求中根据多个条件和函数进行聚合:

SELECT
    countIf((status = 'confirmed') AND (confirm_time > (create_time + toIntervalMinute(1)))) AS num_confirmed_checked,
    sumIf(total_amount, (status = 'confirmed') AND (confirm_time > (create_time + toIntervalMinute(1)))) AS confirmed_checked_amount,
    countIf(status = 'declined') AS num_declined,
    sumIf(total_amount, status = 'declined') AS dec_amount,
    avgIf(total_amount, status = 'declined') AS dec_average
FROM payments

┌─num_confirmed_checked─┬─confirmed_checked_amount─┬─num_declined─┬────────dec_amount─┬───────dec_average─┐
│                    39 │        11195.98991394043 │           50 │ 10780.18000793457 │ 215.6036001586914 │
└───────────────────────┴──────────────────────────┴──────────────┴───────────────────┴───────────────────┘

仅对唯一条目进行聚合

计算唯一条目的数量是一种常见情况。ClickHouse有几种方法可以使用COUNT(DISTINCT col)(与uniqExact相同),或当估计(但更快)的值足够时,使用uniq()来执行此操作。但是,我们可能希望在不同的聚合函数中使用在列中的唯一值。为此,可以使用Distinct组合器:

图片

一旦将Distinct添加到聚合函数中,它将忽略重复的值:

SELECT
    countDistinct(toHour(create_time)) AS hours,
    avgDistinct(toHour(create_time)) AS avg_hour,
    avg(toHour(create_time)) AS avg_hour_all
FROM payments

┌─hours─┬─avg_hour─┬─avg_hour_all─┐
│     2 │     13.5 │        13.74 │
└───────┴──────────┴──────────────┘

在这里,avg_hour 将基于仅两个唯一值计算,而avg_hour_all将基于表中的所有100条记录计算。

结合 Distinct 和 If

由于组合器可以互相结合,可以使用前面的组合器和avgDistinctIf函数来处理更高级的逻辑:

SELECT avgDistinctIf(toHour(create_time), total_amount > 400) AS avg_hour
FROM payments

┌─avg_hour─┐
│       13 │
└──────────┘

这将计算总金额值大于400的记录的不同小时的平均值。

将数据分组后进行聚合

与最小/最大分析不同,我们可能希望在聚合之前将数据分成组,并针对每个组分别计算数据。这可以通过Resample组合器来解决。

它接受一个列、范围(开始/结束)和您希望使用的分割数据的步长。然后,它为每个组返回一个聚合值:

图片

假设我们想根据total_amount从0(最小值)到500(最大值)以100的步长拆分我们的payments表数据。然后,我们想知道每个组中有多少条目以各组的平均总和:

SELECT
    countResample(0, 500, 100)(toInt16(total_amount)) AS group_entries,
    avgResample(0, 500, 100)(total_amount, toInt16(total_amount)) AS group_totals
FROM payments
FORMAT Vertical

Row 1:
──────
group_entries: [21,20,24,31,4]
group_totals:  [50.21238123802912,157.32600135803222,246.1433334350586,356.2583834740423,415.2425003051758]

在这里,countResample()函数计算每个组中的条目数,avgResample()函数计算每个组的total_amount的平均值。Resample组合器接受要基于的列名作为组合函数的最后一个参数。

请注意,countResample()函数只有一个参数(因为count()根本不需要参数),avgResample()有两个参数(第一个是要计算平均值的列)。最后,由于Resample组合器需要,我们必须使用toInt16将total_amount转换为整数。

为了在表格布局中获取Resample()组合器的输出,我们可以使用arrayZip()和arrayJoin()函数:

SELECT
    round(tp.2, 2) AS avg_total,
    tp.1 AS entries
FROM
(
    SELECT
      arrayJoin(arrayZip(countResample(0, 500, 100)(toInt16(total_amount)),
      avgResample(0, 500, 100)(total_amount, toInt16(total_amount)))) AS tp
    FROM payments
)

┌─avg_total─┬─entries─┐
│     50.21 │      21 │
│    157.33 │      20 │
│    246.14 │      24 │
│    356.26 │      31 │
│    415.24 │       4 │
└───────────┴─────────┘

在这里,我们将两个数组的相应值组合成元组,并使用arrayJoin()函数将结果数组展开成表格:

控制空结果的聚合值

聚合函数对结果集不包含数据的情况有不同的反应。例如,count()将返回0,而avg()将产生nan值。

我们可以使用OrDefault()和OrNull()组合器来控制此行为。两者都会更改在数据集为空时使用的聚合函数的返回值:

  • OrDefault()将返回函数的默认值而不是nan,

  • OrNull()将返回NULL(并且还将更改返回类型为Nullable)。

考虑以下示例:

SELECT
    count(),
    countOrNull(),
    avg(total_amount),
    avgOrDefault(total_amount),
    sumOrNull(total_amount)
FROM payments
WHERE total_amount > 1000

┌─count()─┬─countOrNull()─┬─avg(total_amount)─┬─avgOrDefault(total_amount)─┬─sumOrNull(total_amount)─┐
│       0 │          ᴺᵁᴸᴸ │               nan │                          0 │                    ᴺᵁᴸᴸ │
└─────────┴───────────────┴───────────────────┴────────────────────────────┴─────────────────────────┘

正如我们在第一列中看到的,没有返回任何行。请注意,countOrNull()将返回NULL而不是0,avgOrDefault()会返回0而不是nan。

与其他组合器一起使用

与所有其他组合器一样,OrNull()和OrDefault()可以与不同的组合器一起使用以进行更高级的逻辑:

SELECT
    sumIfOrNull(total_amount, status = 'declined') AS declined,
    countIfDistinctOrNull(total_amount, status = 'confirmed') AS confirmed_distinct
FROM payments
WHERE total_amount > 420

┌─declined─┬─confirmed_distinct─┐
│     ᴺᵁᴸᴸ │                  1 │
└──────────┴────────────────────┘

我们使用了sumIfOrNull()组合函数来仅计算被拒绝的付款,并在空集上返回NULL。countIfDistinctOrNull()函数计算不同的total_amount值,但仅适用于满足指定条件的行。

聚合数组

ClickHouse的Array类型在其用户中很受欢迎,因为它为表结构带来了很多灵活性。为了有效地操作Array列,ClickHouse提供了一组数组函数。为了简化对Array类型的聚合,ClickHouse提供了Array()组合器。这些将给定的聚合函数应用于数组列中的所有值,而不是数组本身:

图片

假设我们有以下表格(用示例数据填充):

CREATE TABLE article_reads
(
    `time` DateTime,
    `article_id` UInt32,
    `sections` Array(UInt16),
    `times` Array(UInt16),
    `user_id` UInt32
)
ENGINE = MergeTree
ORDER BY (article_id, time)

┌────────────────time─┬─article_id─┬─sections─────────────────────┬─times────────────────────────────────┬─user_id─┐
│ 2023-01-18 23:44:17 │         10 │ [16,18,7,21,23,22,11,19,9,8] │ [82,96,294,253,292,66,44,256,222,86] │     424 │
│ 2023-01-20 22:53:00 │         10 │ [21,8]                       │ [30,176]                             │     271 │
│ 2023-01-21 03:05:19 │         10 │ [24,11,23,9]                 │ [178,177,172,105]                    │     536 │
...

这个表用于存储文章里各个片段的阅读数据。当用户阅读一篇文章时,我们将阅读的片段保存到sections数组列中,并将相关的阅读时间保存到times列中。

让我们使用uniqArray()函数计算每篇文章阅读的唯一片段(section)数量,再使用avgArray()得到每个 片段的平均时间:

SELECT
    article_id,
    uniqArray(sections) sections_read,
    round(avgArray(times)) time_per_section
FROM article_reads
GROUP BY article_id

┌─article_id─┬─sections_read─┬─time_per_section─┐
│         14 │            22 │              175 │
│         18 │            25 │              159 │
...
│         17 │            25 │              170 │
└────────────┴───────────────┴──────────────────┘

我们可以使用minArray()和maxArray()函数获取所有文章的最小和最大阅读时间:

SELECT
    minArray(times),
    maxArray(times)
FROM article_reads

┌─minArray(times)─┬─maxArray(times)─┐
│              30 │             300 │
└─────────────────┴─────────────────┘

我们还可以使用groupUniqArray()函数与Array()组合器获取每篇文章的阅读部分列表:

SELECT
    article_id,
    groupUniqArrayArray(sections)
FROM article_reads
GROUP BY article_id

┌─article_id─┬─groupUniqArrayArray(sections)───────────────────────────────────────┐
│         14 │ [16,13,24,8,10,3,9,19,23,14,7,25,2,1,21,18,12,17,22,4,6,5]          │
...
│         17 │ [16,11,13,8,24,10,3,9,23,19,14,7,25,20,2,1,15,21,6,5,12,22,4,17,18] │
└────────────┴─────────────────────────────────────────────────────────────────────┘

另一个流行的函数是any(),它在聚合下返回任何列值,并且还可以与Array组合:

SELECT
    article_id,
    anyArray(sections)
FROM article_reads
GROUP BY article_id

┌─article_id─┬─anyArray(sections)─┐
│         14 │                 19 │
│         18 │                  6 │
│         19 │                 25 │
│         15 │                 15 │
│         20 │                  1 │
│         16 │                 23 │
│         12 │                 16 │
│         11 │                  2 │
│         10 │                 16 │
│         13 │                  9 │
│         17 │                 20 │
└────────────┴────────────────────┘

使用Array与其他组合器

Array组合器可以与任何其他组合器一起使用:

SELECT
    article_id,
    sumArrayIfOrNull(times, length(sections) > 8)
FROM article_reads
GROUP BY article_id

┌─article_id─┬─sumArrayOrNullIf(times, greater(length(sections), 8))─┐
│         14 │                                                  4779 │
│         18 │                                                  3001 │
│         19 │                                                  NULL │
...
│         17 │                                                 14424 │
└────────────┴───────────────────────────────────────────────────────┘

我们使用sumArrayIfOrNull()函数来计算阅读了超过八个部分的文章的总时间。请注意,对于阅读了零个超过八个部分的文章,将返回NULL,因为我们还使用了OrNull()组合器。

如果我们将array函数与组合器一起使用,我们甚至可以处理更高级的情况:

SELECT
    article_id,
    countArray(arrayFilter(x -> (x > 120), times)) AS sections_engaged
FROM article_reads
GROUP BY article_id

┌─article_id─┬─sections_engaged─┐
│         14 │               26 │
│         18 │               44 │
...
│         17 │               98 │
└────────────┴──────────────────┘

在这里,我们首先使用arrayFilter函数过滤times数组,以删除所有小于120秒的值。然后,我们使用countArray来计算每篇文章的过滤时间(在我们的情况下是参与阅读)。

聚合映射

ClickHouse中另一种强大的类型是Map。与数组一样,我们可以使用Map()组合器将聚合应用于此类型。

假设我们有一个包含Map列类型的以下表:

CREATE TABLE page_loads
(
    `time` DateTime,
    `url` String,
    `params` Map(String, UInt32)
)
ENGINE = MergeTree
ORDER BY (url, time)

┌────────────────time─┬─url─┬─params───────────────────────────────┐
│ 2023-01-25 17:44:26 │ /   │ {'load_speed':100,'scroll_depth':59} │
│ 2023-01-25 17:44:37 │ /   │ {'load_speed':400,'scroll_depth':12} │
└─────────────────────┴─────┴──────────────────────────────────────┘

我们可以使用Map()组合器来进行sum()和avg()函数,以获得总加载时间和平均滚动深度:

SELECT
    sumMap(params)['load_speed'] AS total_load_time,
    avgMap(params)['scroll_depth'] AS average_scroll
FROM page_loads

┌─total_load_time─┬─average_scroll─┐
│             500 │           35.5 │
└─────────────────┴────────────────┘

Map()组合器还可以与其他组合器一起使用:

SELECT sumMapIf(params, url = '/404')['scroll_depth'] AS average_scroll FROM page_loads

聚合相应数组值

处理数组列的另一种方法是从两个数组中聚合相应的值。这将导致另一个数组。这可以用于矢量化数据(如矢量或矩阵),通过ForEach()组合器实现:

图片

假设我们有以下包含向量的表格:

SELECT * FROM vectors

┌─title──┬─coordinates─┐
│ first  │ [1,2,3]     │
│ second │ [2,2,2]     │
│ third  │ [0,2,1]     │
└────────┴─────────────┘

为了计算坐标数组(向量)的平均值,我们可以使用avgForEach()组合函数:

SELECT avgForEach(coordinates) FROM vectors

┌─avgForEach(coordinates)─┐
│ [1,2,2]                 │
└─────────────────────────┘

这将要求ClickHouse计算所有坐标数组的第一个元素的平均值,并将其放入结果数组的第一个元素中。然后对第二个和第三个元素重复相同的操作。

当然,还支持与其他组合器一起使用:

SELECT avgForEachIf(coordinates, title != 'second') FROM vectors

┌─avgForEachIf(coordinates, notEquals(title, 'second'))─┐
│ [0.5,2,2]                                             │
└───────────────────────────────────────────────────────┘

使用聚合状态

ClickHouse允许使用中间聚合状态而不是结果值。假设我们需要计算唯一值的计数,但我们不想保存值本身(因为它占用空间)。在这种情况下,我们可以使用uniq()函数的State()组合器来保存中间聚合状态,然后使用Merge()组合器来计算实际值:

SELECT uniqMerge(u)
FROM
(
    SELECT uniqState(number) AS u FROM numbers(5)
    UNION ALL
    SELECT uniqState(number + 1) AS u FROM numbers(5)
)

┌─uniqMerge(u)─┐
│            6 │
└──────────────┘

在这里,第一个嵌套查询将返回1...5数字的唯一计数的状态。第二个嵌套查询为2...6数字返回相同的内容。然后,父查询使用uniqMerge()函数来合并我们的状态并获得我们看到的所有唯一数字的计数:

图片

为什么我们要这样做?简单地因为聚合状态比原始数据占用的空间要小得多。当我们想将此状态存储在磁盘上时,这尤其重要。例如,uniqState()数据占用的空间比100万个整数数字小15倍:

SELECT
    table,
    formatReadableSize(total_bytes) AS size
FROM system.tables
WHERE table LIKE 'numbers%'

┌─table─────────┬─size───────┐
│ numbers       │ 3.82 MiB   │ <- we saved 1 million ints here
│ numbers_state │ 245.62 KiB │ <- we save uniqState for 1m ints here
└───────────────┴────────────┘

ClickHouse为存储聚合状态,并在主键上自动合并它们提供了一个AggregatingMergeTree表引擎。让我们创建一个表,以存储先前示例中每日付款的聚合数据:

CREATE TABLE payments_totals
(
    `date` Date,
    `total_amount` AggregateFunction(sum, Float)
)
ENGINE = AggregatingMergeTree
ORDER BY date

我们使用AggregateFunction类型,让ClickHouse知道我们将存储聚合的总状态而不是标量值。在插入时,我们需要使用sumState函数插入聚合状态:

INSERT INTO payments_totals SELECT
    date(create_time) AS date,
    sumState(total_amount)
FROM payments
WHERE status = 'confirmed'
GROUP BY date

最后,我们需要使用sumMerge()函数获取结果值:

┌─sumMerge(total_amount)─┐
│     12033.219916582108 │
└────────────────────────┘

请注意,ClickHouse提供了一种简便的方法,可以使用基于物化视图的聚合表引擎。ClickHouse还提供了一个SimpleState组合器作为某些聚合函数(如'sum'或'min')的优化版本。

总结

在ClickHouse中,聚合函数组合器为对任何数据结构进行分析查询提供了几乎无限的可能性。我们可以向聚合添加条件,对数组元素应用函数,或者获取中间状态以聚合形式存储数据,但仍可用于查询。

Meetup 活动报名通知

好消息:ClickHouse Shenzhen User Group第1届 Meetup 已经开放报名了,将于2024年1月6日在深圳南山区海天二路33号腾讯滨海大厦举行,扫码免费报名

图片

​​联系我们

手机号:13910395701

邮箱:Tracy.Wang@clickhouse.com

满足您所有的在线分析列式数据库管理需求

【Clickhouse从入门到精通】第40篇:ClickHouse聚合函数体系详解(上)——基础聚合与组合聚合 摘要 本文是ClickHouse聚合函数体系详解(上篇),重点解析基础聚合函数与组合器机制。主要内容包括: 基础聚合函数:详细讲解COUNT、SUM、AVG、MIN/MAX等常用聚合函数的语法特性、NULL值处理规则和性能优化要点,特别对比count()与count(x)的本质区别。 数组聚合函数:介绍groupArray和groupUniqArray的用法,包括数组截断、排序控制等高级特性。 组合器机制:深入剖析ClickHouse特有的-If、-Array、-State、-Merge等组合器原理,展示如 阅读详情

相关推荐

【ClickHouse 技术系列】- ClickHouse 聚合函数和聚合状态

简介:本文翻译自 Altinity 针对 ClickHouse 的系列技术文章。面向联机分析处理(OLAP)的开源分析引擎 ClickHouse,因其优良的查询性能,PB级的数据规模,简单的架构,被国内外公司广泛采用。本系列技术文章,将详细展开介绍 ClickHouse。 前言 本文翻译自 Altinity 针对 ClickHouse 的系列技术文章。面向联机分析处理(OLAP)的开源分析引擎 ClickHouse,因其优良的查询性能,PB 级的数据规模,简单的架构,被国内外公司广泛采用。 阿里云 E

阿里云云栖号 3429

clickhouse--行列转换

clickhouse行专列与列转行的方法

liuyingying0418的博客 1万+

大数据ClickHouse进阶(十三):ClickHouse的GROUP BY 子句

Group By子句又称聚合查询,与MySQL或者Hive中的使用方式一样,但是需要注意一点在Select查询中如果有聚合查询,例如max,min等,与聚合查询出现的字段一定要出现在Group by中,否则语句报错。ClickHouse中的Group by 还可以配合WITH ROLLUP、WITH CUBE、WITH TOTALS三种修饰符获取额外的汇总信息。CUBE 是立方体意思,WITH CUBE会基于聚合键之间所有的组合生成小计信息。

Lansonli(蓝深李)的博客 2606

在 ClickHouse 中使用聚合组合器

聚合函数组合器为ClickHouse中的任何数据结构上的分析查询带来了几乎无限的可能性。我们可以为聚合添加条件,对数组元素应用函数,或获取中间状态以以聚合形式存储数据,但仍可用于查询。征稿启示面向社区长期正文,文章内容包括但不限于关于 ClickHouse 的技术研究、项目实践和创新做法等。建议行文风格干货输出&图文并茂。质量合格的文章将会发布在本公众号,优秀者也有机会推荐到 ClickHouse 官网。

ClickHouseDB的博客 3028

ClickHouse 实战:如何使用聚合组合器

ClickHouse 不仅支持标准聚合函数,还提供了大量更高级的函数以满足大多数分析场景的需求。除了聚合函数之外,ClickHouse 还提供了聚合组合器,这是对查询能力的强大扩展,能够应对海量复杂需求。

SmartSi 715

Clickhouse—聚合函数组合

我们在聚合函数的基础上加上一定的组合条件可以改变原来聚合函数的工作方式,例如汇总满足条件的数据,所以组合的方式可以简化SQL 的写法。

4万+

clickhouse学习笔记-7-数据聚合

一、数值运算 sum 简单求和 sumWithOverflow 同步求和参数的数据类型,只适用于数字 sumIf 条件求和 ifNull(x, alt) x - 是否为空值 alt - 为空,函数返回的值 intDivOrZero 除法 round 二、类型判断 ifNull 三、分组 argMin、argMax argMin(arg, val) 取val最小时的arg值。如果有多个arg对应同一个最小值val,取遇到的第一个值,argMax同理 -- 应用 SEL

hjklnmyuiop的博客 1767

Flink CDC 实战:5分钟搞定PostgreSQL数据实时同步(附避坑指南)

本文详细介绍了如何使用Flink CDC实现PostgreSQL数据的实时同步,包括环境配置、逻辑复制槽创建、Flink环境搭建及实战验证。通过5分钟快速指南,帮助开发者高效搭建实时数据管道,并提供了常见问题排查和生产环境优化建议。

red88的博客 818

ClickHouse技术分享第二弹(英文讲义)

前言 以下是今天为公司小伙伴们做的ClickHouse技术分享的讲义。由于PPT太难做了,索性直接用Markdown来写,搭配Chrome上的Markdown Preview Plus插件来渲染,效果非常好。 以下全文奉上,浓缩的都是精华,包含之前写过的两篇文章《物化视图简介与ClickHouse中的应用示例》和《ClickHouse Better Practices》中的全部内容,另外也包含一些...

LittleMagic's Blog 2463

Aurora 8B/10B IP核介绍 —— Xilinx 技术文档Pg046

一、概述该IP核与用户接口之间支持AXI4-Stream协议,且基于ZYNQ SOC、A7、K7、V7以及UltraScale、UltraScale+系列FPGA的高速收发器(the high-speed serial transceivers)进行实现。多达 16 个连续绑定4 个连续绑定的 GTP 收发器framingstreaming以及全双工或单工加扰消扰CRC校验热插拔Aurora 8B/10B核心(图1-1)是一种可扩展的、轻量级的、用于高速串行通信的链路层协议;

qq_32147275的博客 1639

微型纵向加密在新能源场站中的实战部署与运维避坑指南

本文详细解析了微型纵向加密在新能源场站中的实战部署与运维技巧。通过国密算法SM4实现数据加密,确保新能源场站通信安全,同时提供非侵入式部署方案和运维避坑指南,帮助提升网络稳定性和运维效率。

weixin_30505225的博客 595

ClickHouse聚合函数组合器深度解析

ClickHouse聚合函数组合器深度解析 【免费下载链接】ClickHouse ClickHouse® 是一个免费的大数据分析型数据库管理系统。 项目地址: https://gitcode.com/GitHub_Trending...

gitblog_00894的博客 516

掌控板玩板指南1:初识掌控板、扩展板、Mind+编辑器

掌控板、I/O扩展板入门

好乐无荒之地 1万+

ClickHouse聚合组合器:提升OLAP分析效率的利器

聚合函数是数据分析的核心技术,通过将多行数据聚合成单个值实现数据摘要。ClickHouse作为OLAP数据库,其独特的聚合组合器功能通过修饰基础聚合函数,实现了条件聚合、数组处理等高级分析能力。从技术原理看,组合器采用统一的语法结构,在查询执行早期应用过滤条件,大幅减少数据处理量。这种设计在用户行为分析、实时UV统计等场景中,相比传统方法能提升3-5倍性能。特别是在处理电商漏斗分析和系统日志优化时,组合器能显著降低内存消耗80%以上。掌握uniqCombined、countIf等核心组合器,配合State/

weixin_34101914的博客 289

VCS的增量和分离编译

vcs的增量和分离编译

yunduor909的博客 3302

详解AUTOSAR:DaVinci Configurator导入ARXML配置(拓展篇—2)

DaVinci Configurator导入ARXML配置。

不脱发的程序猿 3328

【ClickHouse系列】ClickHouse常用聚合函数的使用方法

本文主要介绍下 ClickHouse 中常用的聚合函数。

一只努力的微服务 5413

YOLOv11 知识蒸馏完整实战:Teacher–Student 训练策略与性能飞跃

在self.alpha = alpha # 蒸馏损失权重self.temperature = temperature # 温度系数,控制分布平滑度# 输出分布蒸馏(KL散度损失)# 中间特征蒸馏(MSE损失,对齐中间层特征)# 总蒸馏损失知识蒸馏是YOLOv11在“小模型高性能部署”场景的“破局之法”——它让小模型能“站在大模型的肩膀上”,兼具速度与精度。从损失函数定义到多阶段训练,再到实战落地,本教程已为你铺就了一条清晰的路径。

m0_64661770的博客 141

clickhouse普通函数,聚合函数使用总结

## 一.创建clickhouse表 ### 1.建表 CREATE TABLE ck_test ( `id` String COMMENT 'id', `int_1` UInt32 COMMENT '整型列1', `int_2` UInt32 COMMENT '整型列2', `str_1` String COMMENT '字符串列1', `str_2` String COMMENT '字符串列2' ) ENGINE = MergeTree ORDER BY id...

dair6的博客 9128

【LAMMPS学习】八、基础知识(2.1)2D模拟

此部分描述了如何使用 LAMMPS 为用户和开发人员执行各种任务。术语表页面还列出了 MD 术语,以及相应 LAMMPS 手册页的链接。LAMMPS 源代码分发的examples目录中包含的示例输入脚本以及示例脚本页面上突出显示的示例输入脚本还展示了如何设置和运行各种模拟。

荷塘阅色 1249

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

MySQL postgresql clickhouse 关于String的聚合函数

MySQL postgresql clickhouse String聚合函数前言一、mysql1. 准备表2.测试二、postgresql1.测试代码click house 前言 数据库迁移(postgre to clickhouse) 遇到 String聚合函数相关的问题 特此记录 一、mysql 方法名称为 group_concat () group_concat ()函数将组中的字符串连接成为具有各种选项的单个字符串 具体使用方法如下: GROUP_CONCAT(DISTINCT express

Delete丶S的博客 1518

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

ClickHouse聚合函数完全指南:从基础统计到自定义复杂计算

ClickHouse® 是一个免费的大数据分析型数据库管理系统,以其卓越的列式存储和向量化查询处理能力而闻名。在ClickHouse中,聚合函数是实现高效数据分析的核心组件,能够对海量数据进行快速统计计算。本文将详细介绍ClickHouse聚合函数的完整体系,从基础聚合到自定义复杂统计计算,帮助您充分利用这一强大功能进行大数据分析。🚀 ## ClickHouse聚合函数体系概览 ClickH

gitblog_01075的博客 1013

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

ClickHouse 聚合查询优化

按某个维度求和,基于原始数据每次计算效率较低,可以使用 SummingMergeTree 做预聚合,之后只需要查询预聚合结果即可。通过 ClickHouse 的 SummingMergeTree 引擎,我们可以大幅优化这个查询。由于新的查询语句只需要处理预聚合表,可以大幅加速查询速度,并降低 ClickHouse 的负载。一个生产系统中的每天日志数可能是几亿或者几十亿条,这样查询效率很低。然后插入存量数据(如果有的话)好久没写,水一篇凑个数。有一些大表,我们需要。

felix021的专栏 378
上一篇: 激发大规模ClickHouse数据加载(3/3)确保加载大规模数据的可靠性
下一篇: ClickHouse 23.11 版本发布说明
ClickHouseDB
博客等级 码龄3年 1707粉丝 320原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值