ClickHouse 24.4 版本发布说明

news2024/10/5 16:47:32

图片

本文字数:13148;估计阅读时间:33 分钟

审校:庄晓东(魏庄)

本文在公众号【ClickHouseInc】首发

图片

新的一个月意味着新版本的发布!

发布概要

本次ClickHouse 24.4版本包含了13个新功能🎁、16个性能优化🛷、65个bug修复🐛

贡献者名单

和往常一样,我们向 24.4 版本中的所有新贡献者表示热烈欢迎!ClickHouse 的受欢迎程度在很大程度上归功于社区的努力。看到社区不断壮大总是令人感到骄傲。

以下是新贡献者的姓名:

Alexey Katsman、Anita Hammer、Arnaud Rocher、Chandre Van Der Westhuizen、Eduard Karacharov、Eliot Hautefeuille、Igor Markelov、Ilya Andreev、Jhonso7393、Joseph Redfern、Josh Rodriguez、Kirill、KrJin、Maciej Bak、Murat Khairulin、Paweł Kudzia、Tristan、dilet6298、loselarry

如果你想知道我们是如何生成这个列表的…… 点这里【https://gist.github.com/gingerwizard/5a9a87a39ba93b422d8640d811e269e9】。

递归CTE

由 Maksim Kita 贡献

SQL:1999引入了递归公共表达式(CTE)用于层次查询,从而将SQL扩展为图灵完备的编程语言。

至今,ClickHouse一直通过利用层次字典来支持层次查询。有了我们新的默认启用的查询分析和优化基础设施,我们终于有了引入了期待已久的强大功能,例如递归CTE。

ClickHouse的递归CTE采用标准的SQL:1999语法,并通过了递归CTE的所有PostgreSQL测试。此外,ClickHouse现在对递归CTE的支持甚至超过了PostgreSQL。在CTE的UNION ALL子句的底部,可以指定多个(任意复杂的)查询,可以多次引用CTE的基表等。

递归CTE可以优雅而简单地解决层次问题。例如,它们可以轻松回答层次数据模型(例如树和图)的可达性问题。

具体来说,递归CTE可以计算关系的传递闭包,这意味着它可以找出所有可能的间接连接。以伦敦地铁的站点连接为例,您可以想象到所有直接相连的地铁站:从牛津街到邦德街,从邦德街到大理石拱门,从大理石拱门到兰开斯特门,等等。这些连接的传递闭包则包含了这些站点之间所有可能的连接,例如:从牛津街到兰开斯特门,从牛津街到大理石拱门,等等。

为了演示这一点,我们使用了一个模拟伦敦地铁所有连接的数据集,其中每个条目表示两个直接相连的站点。然后,我们可以使用递归CTE来轻松回答这样的问题:

当从中央线的牛津街站出发时,我们最多可以在五次停靠内到达哪些站点?

我们用中央线站点地图的截图来进行可视化:

图片

我们为存储伦敦地铁连接数据集创建了一个ClickHouse表:

CREATE OR REPLACE TABLE Connections (
    Station_1 String,
    Station_2 String,
    Line String,
    PRIMARY KEY(Line, Station_1, Station_2)
);

值得注意的是,我们在上面的DDL语句中没有指定表引擎(这是自从ClickHouse 24.3之后才可能的),并且在列定义中使用了PRIMARY KEY语法(自从ClickHouse 23.7以来就可行了)。通过这样的设置,不仅我们的递归CTEs,连同我们的ClickHouse表DDL语法也符合SQL的标准。

我们利用url表函数和自动模式推断,直接将数据集加载到我们的表中:

INSERT INTO Connections
SELECT * FROM url('https://datasets-documentation.s3.eu-west-3.amazonaws.com/london_underground/london_connections.csv')

加载后的数据如下所示:

SELECT
    *
FROM Connections
WHERE Line = 'Central Line'
ORDER BY Station_1, Station_2
LIMIT 10;

    ┌─Station_1──────┬─Station_2────────┬─Line─────────┐
 1. │ Bank           │ Liverpool Street │ Central Line │
 2. │ Bank           │ St. Paul's       │ Central Line │
 3. │ Barkingside    │ Fairlop          │ Central Line │
 4. │ Barkingside    │ Newbury Park     │ Central Line │
 5. │ Bethnal Green  │ Liverpool Street │ Central Line │
 6. │ Bethnal Green  │ Mile End         │ Central Line │
 7. │ Bond Street    │ Marble Arch      │ Central Line │
 8. │ Bond Street    │ Oxford Circus    │ Central Line │
 9. │ Buckhurst Hill │ Loughton         │ Central Line │
10. │ Buckhurst Hill │ Woodford         │ Central Line │
    └────────────────┴──────────────────┴──────────────┘

接着,我们使用递归CTE来回答上述问题:

WITH RECURSIVE Reachable_Stations AS
(
    SELECT Station_1, Station_2, Line, 1 AS stops
    FROM Connections
    WHERE Line = 'Central Line'
      AND Station_1 = 'Oxford Circus'
    UNION ALL
    SELECT rs.Station_1, c.Station_2, c.Line, rs.stops + 1 AS stops
    FROM Reachable_Stations AS rs, Connections AS c
    WHERE rs.Line = c.Line
      AND rs.Station_2 = c.Station_1
      AND rs.stops < 5
)
SELECT DISTINCT (Station_1, Station_2, stops) AS connections
FROM Reachable_Stations
ORDER BY stops ASC;

结果如下所示:

    ┌─connections────────────────────────────────┐
 1. │ ('Oxford Circus','Bond Street',1)          │
 2. │ ('Oxford Circus','Tottenham Court Road',1) │
 3. │ ('Oxford Circus','Marble Arch',2)          │
 4. │ ('Oxford Circus','Oxford Circus',2)        │
 5. │ ('Oxford Circus','Holborn',2)              │
 6. │ ('Oxford Circus','Bond Street',3)          │
 7. │ ('Oxford Circus','Lancaster Gate',3)       │
 8. │ ('Oxford Circus','Tottenham Court Road',3) │
 9. │ ('Oxford Circus','Chancery Lane',3)        │
10. │ ('Oxford Circus','Marble Arch',4)          │
11. │ ('Oxford Circus','Oxford Circus',4)        │
12. │ ('Oxford Circus','Queensway',4)            │
13. │ ('Oxford Circus','Holborn',4)              │
14. │ ('Oxford Circus','St. Paul\'s',4)          │
15. │ ('Oxford Circus','Bond Street',5)          │
16. │ ('Oxford Circus','Lancaster Gate',5)       │
17. │ ('Oxford Circus','Tottenham Court Road',5) │
18. │ ('Oxford Circus','Notting Hill Gate',5)    │
19. │ ('Oxford Circus','Chancery Lane',5)        │
20. │ ('Oxford Circus','Bank',5)                 │
    └────────────────────────────────────────────┘

递归CTE具有简单的迭代执行逻辑,类似于递归的自我连接,一直连接下去,直到找不到新的连接伙伴或满足中止条件。因此,我们上面的CTE首先执行UNION ALL子句的顶部部分,查询我们的Connections表,找到所有直接连接到中央线上的牛津街站的站点。这将返回一个表,它绑定到Reachable_Stations标识符,并且看起来像这样:

Initial Reachable_Stations table content
 ┌─Station_1─────┬─Station_2────────────┐
 │ Oxford Circus │ Bond Street          │
 │ Oxford Circus │ Tottenham Court Road │
 └───────────────┴──────────────────────┘

从现在开始,只有CTE的UNION ALL子句的底部部分将被执行(递归执行):

Reachable_StationsConnections表连接,找到那些在Connections表中的Station_1值与Reachable_StationsStation_2值匹配的连接伙伴。

Connections table join partners

┌─Station_1────────────┬─Station_2─────┐
│ Bond Street          │ Marble Arch   │
│ Bond Street          │ Oxford Circus │
│ Tottenham Court Road │ Holborn       │
│ Tottenham Court Road │ Oxford Circus │
└──────────────────────┴───────────────┘

通过UNION ALL子句,这些连接伙伴被添加到Reachable_Stations表中,标记了递归CTE的第一次迭代的完成。在接下来的迭代中,我们执行CTE的UNION ALL子句的底部部分,继续将Reachable_StationsConnections表连接,以识别(并添加到Reachable_Stations中)所有在Connections表中的Station_1值与Reachable_StationsStation_2值匹配的新连接伙伴。这些迭代将持续进行,直到找不到新的连接伙伴或满足停止条件。在我们的查询中,我们使用一个停靠计数器来在达到从起始站点允许的停靠数时中止CTE的迭代循环。

需要注意的是,结果中将牛津街站列为从牛津街站到达的站点,分别需要2和4次停靠。这在理论上是正确的,但并不是非常实际,这是因为我们的查询不考虑任何方向或循环。我们把这留给读者作为一个有趣的练习。

作为一个附加问题,我们感兴趣的是从中央线的牛津街站到达斯特拉特福站需要多少次停靠。我们再次用中央线地图来可视化这个问题:

图片

为此,我们只需修改递归CTE的中止条件(一旦添加了具有Stratford作为目标站点的连接伙伴到CTE表中,就停止CTE的连接迭代):

WITH RECURSIVE Reachable_Stations AS
(
    SELECT Station_1, Station_2, Line, 1 AS stops
    FROM Connections
    WHERE Line = 'Central Line'
      AND Station_1 = 'Oxford Circus'
  UNION ALL
    SELECT rs.Station_1 c.Station_2, c.Line, rs.stops + 1 AS stops
    FROM Reachable_Stations AS rs, Connections AS c
    WHERE rs.Line = c.Line
      AND rs.Station_2 = c.Station_1
      AND 'Stratford' NOT IN (SELECT Station_2 FROM Reachable_Stations)
)
SELECT max(stops) as stops
FROM Reachable_Stations;

结果显示,从牛津街站到达斯特拉特福站需要9次停靠,与上述中央线地图计划相匹配。

   ┌─stops─┐
1. │     9 │
   └───────┘

递归CTE可以轻松回答关于这个数据集的更有趣的问题。例如,原始版本数据集中的相对连接时间可以用来找出从牛津街站希思罗机场站的最快连接(跨越地铁线)。敬请期待在单独的后续文章中解决这个问题。

QUALIFY

由 Maksim Kita 贡献

这个版本新增的另一个功能是QUALIFY子句,它允许我们根据窗口函数的值进行筛选。

我们将通过窗口函数 - 排名示例来演示如何使用它。数据集包含假设的足球运动员及其薪水。我们可以像这样将其导入到ClickHouse中:

CREATE TABLE salaries ORDER BY team AS
FROM url('https://raw.githubusercontent.com/ClickHouse/examples/main/LearnClickHouseWithMark/WindowFunctions-Aggregation/data/salaries.csv')
SELECT * EXCEPT (weeklySalary), weeklySalary AS salary
SETTINGS schema_inference_make_columns_nullable=0;

让我们快速查看薪水表中的数据:

SELECT * FROM salaries LIMIT 5;
   ┌─team──────────────┬─player───────────┬─position─┬─salary─┐
1. │ Aaronbury Seekers │ David Morton     │ D        │  63014 │
2. │ Aaronbury Seekers │ Edwin Houston    │ D        │  51751 │
3. │ Aaronbury Seekers │ Stephen Griffith │ M        │ 181825 │
4. │ Aaronbury Seekers │ Douglas Clay     │ F        │  73436 │
5. │ Aaronbury Seekers │ Joel Mendoza     │ D        │ 257848 │
   └───────────────────┴──────────────────┴──────────┴────────┘

接下来,让我们计算每个球员所在位置的薪水排名。即,他们相对于在同一位置上踢球的人来说薪水有多少?

SELECT player, team, position AS pos, salary,
       rank() OVER (PARTITION BY position ORDER BY salary DESC) AS posRank
FROM salaries
ORDER BY salary DESC
LIMIT 5
   ┌─player──────────┬─team────────────────────┬─pos─┬─salary─┬─posRank─┐
1. │ Robert Griffin  │ North Pamela Trojans    │ GK  │ 399999 │       1 │
2. │ Scott Chavez    │ Maryhaven Generals      │ M   │ 399998 │       1 │
3. │ Dan Conner      │ Michaelborough Rogues   │ M   │ 399998 │       1 │
4. │ Nathan Thompson │ Jimmyville Legionnaires │ D   │ 399998 │       1 │
5. │ Benjamin Cline  │ Stephaniemouth Trojans  │ D   │ 399998 │       1 │
   └─────────────────┴─────────────────────────┴─────┴────────┴─────────┘

假设我们想要通过位置排名(posRank)来筛选出薪水最高的前3名球员。我们可能会尝试添加一个WHERE子句来实现这一目标:

SELECT player, team, position AS pos, salary,
       rank() OVER (PARTITION BY position ORDER BY salary DESC) AS posRank
FROM salaries
WHERE posRank <= 3
ORDER BY salary DESC
LIMIT 5
Received exception:
Code: 184. DB::Exception: Window function rank() OVER (PARTITION BY position ORDER BY salary DESC) AS posRank is found in WHERE in query. (ILLEGAL_AGGREGATION)

但由于WHERE子句在窗口函数评估之前运行,这样是行不通的。在24.4版本发布之前,我们可以通过引入CTE来绕过这个问题:

WITH salaryRankings AS
    (
        SELECT player, 
               if(
                 length(team) <=25, 
                 team, 
                 concat(substring(team, 5), 1, '...')
               ) AS team, 
               position AS pos, salary,
               rank() OVER (
                 PARTITION BY position 
                 ORDER BY salary DESC
               ) AS posRank
        FROM salaries
        ORDER BY salary DESC
    )
SELECT *
FROM salaryRankings
WHERE posRank <= 3
    ┌─player────────────┬─team────────────────────┬─pos─┬─salary─┬─posRank─┐
 1. │ Robert Griffin    │ North Pamela Trojans    │ GK  │ 399999 │       1 │
 2. │ Scott Chavez      │ Maryhaven Generals      │ M   │ 399998 │       1 │
 3. │ Dan Conner        │ Michaelborough Rogue... │ M   │ 399998 │       1 │
 4. │ Benjamin Cline    │ Stephaniemouth Troja... │ D   │ 399998 │       1 │
 5. │ Nathan Thompson   │ Jimmyville Legionnai... │ D   │ 399998 │       1 │
 6. │ William Rubio     │ Nobleview Sages         │ M   │ 399997 │       3 │
 7. │ Juan Bird         │ North Krystal Knight... │ GK  │ 399986 │       2 │
 8. │ John Lewis        │ Andreaberg Necromanc... │ D   │ 399985 │       3 │
 9. │ Michael Holloway  │ Alyssaborough Sages     │ GK  │ 399984 │       3 │
10. │ Larry Buchanan    │ Eddieshire Discovere... │ F   │ 399973 │       1 │
11. │ Alexis Valenzuela │ Aaronport Crusaders     │ F   │ 399972 │       2 │
12. │ Mark Villegas     │ East Michaelborough ... │ F   │ 399972 │       2 │
    └───────────────────┴─────────────────────────┴─────┴────────┴─────────┘

尽管这个查询是有效的,但它相当繁琐。现在有了QUALIFY子句,我们可以在不需要引入CTE的情况下筛选数据,如下所示:

SELECT player, team, position AS pos, salary,
       rank() OVER (PARTITION BY position ORDER BY salary DESC) AS posRank
FROM salaries
QUALIFY posRank <= 3
ORDER BY salary DESC;

接着,我们将得到和以前相同的结果。

Join 的性能提升

由 Maksim Kita 贡献

此外,针对某些特定的JOIN使用情况,还进行了一些性能改进。

首先是谓词下推的改进,即分析器确定筛选条件可以应用于JOIN的两侧时的优化。

让我们通过一个示例来说明,我们使用The OpenSky数据集,该数据集包含2019年至2021年的航空数据。我们想要获取经过旧金山的十次航班的列表,可以使用以下查询来实现:

SELECT
    l.origin,
    r.destination AS dest,
    firstseen,
    lastseen
FROM opensky AS l
INNER JOIN opensky AS r ON l.destination = r.origin
WHERE notEmpty(l.origin) AND notEmpty(r.destination) AND (r.origin = 'KSFO')
LIMIT 10
SETTINGS optimize_move_to_prewhere = 0

为了避免ClickHouse执行另一项优化,我们禁用了optimize_move_to_prewhere,这样我们就能看到JOIN改进带来的好处。如果我们在24.3上运行此查询,结果将如下所示:

    ┌─origin─┬─dest─┬───────────firstseen─┬────────────lastseen─┐
 1. │ 00WA   │ 00CL │ 2019-10-14 21:03:19 │ 2019-10-14 22:42:01 │
 2. │ 00WA   │ ZGGG │ 2019-10-14 21:03:19 │ 2019-10-14 22:42:01 │
 3. │ 00WA   │ ZGGG │ 2019-10-14 21:03:19 │ 2019-10-14 22:42:01 │
 4. │ 00WA   │ ZGGG │ 2019-10-14 21:03:19 │ 2019-10-14 22:42:01 │
 5. │ 00WA   │ ZGGG │ 2019-10-14 21:03:19 │ 2019-10-14 22:42:01 │
 6. │ 00WA   │ ZGGG │ 2019-10-14 21:03:19 │ 2019-10-14 22:42:01 │
 7. │ 00WA   │ ZGGG │ 2019-10-14 21:03:19 │ 2019-10-14 22:42:01 │
 8. │ 00WA   │ YSSY │ 2019-10-14 21:03:19 │ 2019-10-14 22:42:01 │
 9. │ 00WA   │ YSSY │ 2019-10-14 21:03:19 │ 2019-10-14 22:42:01 │
10. │ 00WA   │ YSSY │ 2019-10-14 21:03:19 │ 2019-10-14 22:42:01 │
    └────────┴──────┴─────────────────────┴─────────────────────┘

10 rows in set. Elapsed: 0.656 sec. Processed 15.59 million rows, 451.90 MB (23.75 million rows/s., 688.34 MB/s.)
Peak memory usage: 62.79 MiB.

让我们看看 24.4 的表现:

    ┌─origin─┬─dest─┬───────────firstseen─┬────────────lastseen─┐
 1. │ 00WA   │ 00CL │ 2019-10-14 21:03:19 │ 2019-10-14 22:42:01 │
 2. │ 00WA   │ ZGGG │ 2019-10-14 21:03:19 │ 2019-10-14 22:42:01 │
 3. │ 00WA   │ ZGGG │ 2019-10-14 21:03:19 │ 2019-10-14 22:42:01 │
 4. │ 00WA   │ ZGGG │ 2019-10-14 21:03:19 │ 2019-10-14 22:42:01 │
 5. │ 00WA   │ ZGGG │ 2019-10-14 21:03:19 │ 2019-10-14 22:42:01 │
 6. │ 00WA   │ ZGGG │ 2019-10-14 21:03:19 │ 2019-10-14 22:42:01 │
 7. │ 00WA   │ ZGGG │ 2019-10-14 21:03:19 │ 2019-10-14 22:42:01 │
 8. │ 00WA   │ YSSY │ 2019-10-14 21:03:19 │ 2019-10-14 22:42:01 │
 9. │ 00WA   │ YSSY │ 2019-10-14 21:03:19 │ 2019-10-14 22:42:01 │
10. │ 00WA   │ YSSY │ 2019-10-14 21:03:19 │ 2019-10-14 22:42:01 │
    └────────┴──────┴─────────────────────┴─────────────────────┘

10 rows in set. Elapsed: 0.079 sec.

查询速度提升了约8倍。如果我们通过SELECT *返回所有列,那么在24.3中,此查询所花费的时间会增加到超过4秒,在24.4中则为0.4秒,这是一个10倍的改进。

让我们来看看为什么查询更快。其中两行很关键:

INNER JOIN opensky AS r ON l.destination = r.origin
WHERE notEmpty(l.origin) AND notEmpty(r.destination) AND (r.origin = 'KSFO')

我们WHERE子句的最后一个条件是r.origin = 'KSFO'。在上一行中,我们指定只有当l.destination = r.origin时才进行连接,这意味着l.destination也必须是'KSFO'。24.4版本中的分析器知道这一点,因此可以更早地过滤掉很多行。

换句话说,在24.4中,我们的WHERE子句实际上是这样的

INNER JOIN opensky AS r ON l.destination = r.origin
WHERE notEmpty(l.origin) AND notEmpty(r.destination) 
AND (r.origin = 'KSFO') AND (l.destination = 'KSFO')

第二个改进是,如果JOIN后的谓词过滤掉任何未连接的行,分析器现在会自动将OUTER JOIN转换为INNER JOIN

举个例子,假设我们最初编写了一个查询来查找旧金山和纽约之间的航班,捕捉直达航班和有中转的航班。

SELECT
    l.origin,
    l.destination,
    r.destination,
    registration,
    l.callsign,
    r.callsign
FROM opensky AS l
LEFT JOIN opensky AS r ON l.destination = r.origin
WHERE notEmpty(l.destination) 
AND (l.origin = 'KSFO') 
AND (r.destination = 'KJFK') 
LIMIT 10

后来我们添加了一个额外的过滤器,只返回r.callsign = 'AAL1424'的行。

SELECT
    l.origin,
    l.destination AS leftDest,
    r.destination AS rightDest,
    registration AS reg,
    l.callsign,
    r.callsign
FROM opensky AS l
LEFT JOIN opensky AS r ON l.destination = r.origin
WHERE notEmpty(l.destination) 
AND (l.origin = 'KSFO') 
AND (r.destination = 'KJFK') 
AND (r.callsign = 'AAL1424')
LIMIT 10
SETTINGS optimize_move_to_prewhere = 0

由于现在要求JOIN右侧的callsign列具有值,LEFT JOIN可以转换为INNER JOIN。让我们来看看在24.3和24.4中查询性能的变化。

24.3

    ┌─origin─┬─leftDest─┬─rightDest─┬─reg────┬─callsign─┬─r.callsign─┐
 1. │ KSFO   │ 01FA     │ KJFK      │ N12221 │ UAL423   │ AAL1424    │
 2. │ KSFO   │ 01FA     │ KJFK      │ N12221 │ UAL423   │ AAL1424    │
 3. │ KSFO   │ 01FA     │ KJFK      │ N12221 │ UAL423   │ AAL1424    │
 4. │ KSFO   │ 01FA     │ KJFK      │ N12221 │ UAL423   │ AAL1424    │
 5. │ KSFO   │ 01FA     │ KJFK      │ N12221 │ UAL423   │ AAL1424    │
 6. │ KSFO   │ 01FA     │ KJFK      │ N87527 │ UAL423   │ AAL1424    │
 7. │ KSFO   │ 01FA     │ KJFK      │ N87527 │ UAL423   │ AAL1424    │
 8. │ KSFO   │ 01FA     │ KJFK      │ N87527 │ UAL423   │ AAL1424    │
 9. │ KSFO   │ 01FA     │ KJFK      │ N87527 │ UAL423   │ AAL1424    │
10. │ KSFO   │ 01FA     │ KJFK      │ N87527 │ UAL423   │ AAL1424    │
    └────────┴──────────┴───────────┴────────┴──────────┴────────────┘

10 rows in set. Elapsed: 1.937 sec. Processed 63.98 million rows, 2.52 GB (33.03 million rows/s., 1.30 GB/s.)
Peak memory usage: 2.84 GiB.

24.4

    ┌─origin─┬─leftDest─┬─rightDest─┬─reg────┬─callsign─┬─r.callsign─┐
 1. │ KSFO   │ 01FA     │ KJFK      │ N12221 │ UAL423   │ AAL1424    │
 2. │ KSFO   │ 01FA     │ KJFK      │ N12221 │ UAL423   │ AAL1424    │
 3. │ KSFO   │ 01FA     │ KJFK      │ N12221 │ UAL423   │ AAL1424    │
 4. │ KSFO   │ 01FA     │ KJFK      │ N12221 │ UAL423   │ AAL1424    │
 5. │ KSFO   │ 01FA     │ KJFK      │ N12221 │ UAL423   │ AAL1424    │
 6. │ KSFO   │ 01FA     │ KJFK      │ N87527 │ UAL423   │ AAL1424    │
 7. │ KSFO   │ 01FA     │ KJFK      │ N87527 │ UAL423   │ AAL1424    │
 8. │ KSFO   │ 01FA     │ KJFK      │ N87527 │ UAL423   │ AAL1424    │
 9. │ KSFO   │ 01FA     │ KJFK      │ N87527 │ UAL423   │ AAL1424    │
10. │ KSFO   │ 01FA     │ KJFK      │ N87527 │ UAL423   │ AAL1424    │
    └────────┴──────────┴───────────┴────────┴──────────┴────────────┘

10 rows in set. Elapsed: 0.762 sec. Processed 23.22 million rows, 939.75 MB (30.47 million rows/s., 1.23 GB/s.)
Peak memory usage: 9.00 MiB.

在24.4中,查询速度快了将近三倍。

如果您想了解JOIN性能改进是如何实现的,请阅读Maksim Kita的博客文章,他详细解释了所有内容。

关于24.4版本的内容就介绍到这里。我们邀请您参加5月30日举行的24.5版本发布会。请确保注册,这样您就能收到Zoom网络研讨会的所有详情。【https://clickhouse.com/company/events/v24-5-community-release-call】

征稿启示

面向社区长期正文,文章内容包括但不限于关于 ClickHouse 的技术研究、项目实践和创新做法等。建议行文风格干货输出&图文并茂。质量合格的文章将会发布在本公众号,优秀者也有机会推荐到 ClickHouse 官网。请将文章稿件的 WORD 版本发邮件至:Tracy.Wang@clickhouse.com

​​联系我们

手机号:13910395701

邮箱:Tracy.Wang@clickhouse.com

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1695585.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

List Control控件绑定变量

创建基于对话框的mfc项目 添加 List Control控件 右击控件&#xff0c;选择“添加变量” 在初始化对话框代码中增加一些代码 BOOL CMFCApplication3Dlg::OnInitDialog() { //...// TODO: 在此添加额外的初始化代码DWORD dwStyle m_programLangList.GetExtendedStyle(); …

程序员的那些经典段子

哈喽&#xff0c;大家好&#xff0c;我是明智&#xff5e; 本周咱们已经解决了在面试中经常碰到的OOM问题&#xff1a; 《美团一面&#xff0c;发生OOM了&#xff0c;程序还能继续运行吗&#xff1f;》 《美团一面&#xff1a;碰到过OOM吗&#xff1f;你是怎么处理的&#xff1…

【Linux】Linux的基本指令_1

文章目录 二、基本指令1. whoami 和 who2. pwd3. ls4. clear5. mkdir 和 cd6. touch7. rmdir 和 rm 未完待续 二、基本指令 直接在命令行的末尾&#xff08;# 后面&#xff09;输入指令即可。在学习Linux指令的过程中&#xff0c;还会穿插一些关于Linux的知识点。 1. whoami …

AI助力垃圾分类开启智慧环保新时代,基于卷积神经网络模型开发实践垃圾分类识别系统

在快节奏的现代生活中&#xff0c;垃圾分类已经成为一项重要的环保举措。然而&#xff0c;面对日益复杂的垃圾种类和繁多的分类标准&#xff0c;许多人感到困惑和无奈。幸运的是&#xff0c;随着人工智能技术的飞速发展&#xff0c;AI深度学习模型为垃圾分类带来了革命性的变化…

人工智能 框架 paddlepaddle 飞桨 使用指南 使用例子 线性回归模型demo 详解

安装过程&使用指南&线性回归模型 使用例子 本来预想 是安装 到 conda 版本的 11.7的 但是电脑没有gpu 所以 安装过程稍有变动,下面简单讲下 conda create -n paddle_env117 python=3.9 由于想安装11.7版本 py 是3.9 所以虚拟环境名称也是 paddle_env117 activa…

嵌入式全栈开发学习笔记---C语言笔试复习大全21(编程题25~30)

目录 25、实现字符串的排序。&#xff08;输入hello world good&#xff0c;输出good hello world&#xff0c;其中字符串个数任意&#xff09; 26、输入两个有序的字符串&#xff08;从小到大&#xff09;&#xff0c;合并成一个有序的字符串。&#xff08;输入cdhxyz fjln …

利用EAS自动生成数据模型和sql脚本

EAS适用于敏捷开发中小系统,这节主要讲解EAS对应的模型和数据库脚本输出应用。 在这个应用程序中,用户可自定义实体模型和枚举模型,只要选择相应的实体或者枚举进行右击添加即可。 解决方案参数设定,在解决方案的设定中可设置项目名称、通用语言,命名空间和输出位置。 连…

Python+Flask+Pandas怎样实现任意时间范围的对比数据报表

话不多说,有图有源码: 1.上图 2.因为是低代码的,只能发重要有用的代码片段了 实现思路:1)获取指定时间范围内的数据:2)df合并 #----------年份替换----------------for syear in range(int(byear),int(eyear)1):start_datestr(syear)strbdate[4:]end_datestr(syear)stredate…

2024-05-22 VS2022使用modules

点击 <C 语言编程核心突破> 快速C语言入门 VS2022使用modules 前言一、准备二、使用其一, 用VS installer 安装模块:第二个选项就是, 与你的代码一同编译std模块, 这个非常简单, 但是也有坑. 总结 前言 要解决问题: 使用VS2022开启modules. 想到的思路: 跟着官方文档整…

Linux更改系统中的root密码

Linux里面的root密码忘记了怎么办&#xff1f; 1 更改系统中的 root 密码 &#xff08;1&#xff09;键盘 CtrlAltT 快捷键打开终端。 &#xff08;2&#xff09;在终端窗口中输入以下代码&#xff1a; sudo passwd root &#xff08;3&#xff09;输入锁屏密码 &#xf…

kali下载zsteg和stegpy

1.kali下载zsteg 从 GitHub 上克隆zsteg到kali git clone https://github.com/zed-0xff/zsteg 切换目录 cd zsteg 用于安装名为 zsteg 的 Ruby Gem 包 gem install zsteg 2.kali下载stegpy 下载网站内的stegpy-master压缩包GitCode - 开发者的代码家园 并拉到kali中 切换到s…

String s1 = new String(“abc“);这句话创建了几个字符串对象?

首先&#xff0c;我们来聊聊Java中的字符串&#xff08;String&#xff09;。在Java里&#xff0c;字符串是不可变的&#xff0c;也就是说&#xff0c;一旦我们创建了一个字符串&#xff0c;它的值就不能更改了。这涉及到几个核心概念&#xff1a; 字符串常量池&#xff1a;这是…

Pytorch深度学习实践笔记5

&#x1f3ac;个人简介&#xff1a;一个全栈工程师的升级之路&#xff01; &#x1f4cb;个人专栏&#xff1a;pytorch深度学习 &#x1f380;CSDN主页 发狂的小花 &#x1f304;人生秘诀&#xff1a;学习的本质就是极致重复! 视频来自【b站刘二大人】 目录 1 Linear Regress…

Java 登录错误次数限制,用户禁登1小时

手机号验证码登录&#xff0c;验证码输入错误次数超5次封禁 Overridepublic boolean checkCaptcha(String phoneNum, String captcha) {String codeNum (String) redisTemplate.opsForValue().get(UserCacheNames.USER_CAPTCHA phoneNum);if (codeNum null) {throw new Wan…

2024 ISCC pwn wp

iscc 练武pwn 总结第一周chaosISCC_easyFlagshopping 第二周ISCC_easyISCC_Uheapheap 第三周miaoYour_programeazy_heap 总结 总体感觉iscc考察的题目都挺基础的&#xff0c;在目前这种比赛的大环境下&#xff0c;仍然出这种&#xff0c;比较基础的题目&#xff0c;实在是难得…

24李林跌落神坛,880还刷吗?还是换1000、900、660?

“李林今年跌落神坛了&#xff01;” “全是固定题型没新题&#xff0c;结果今年考的全是新题。” 880是“老真题的神”&#xff0c; 遇到24年&#xff0c;冷门考点多&#xff0c;计算量又大&#xff0c;就不灵了。 但“老真题”&#xff0c;还是得刷。就像往年真题是要刷的…

开源大模型与闭源大模型

概述 开源大模型和闭源大模型是两种常见的大模型类型&#xff0c;它们在以下方面存在差异&#xff1a; 开放性&#xff1a; 开源大模型&#xff1a;代码和模型结构是公开可用的&#xff0c;任何人都可以访问、修改和使用。闭源大模型&#xff1a;模型的代码和结构是私有的&…

SAP揭秘者-怎么执行生产订单ATP检查及其注意点

文章摘要&#xff1a; 上篇文章给大家介绍生产订单ATP检查的相关后台配置&#xff0c;大家可以按照配置步骤去进行配置&#xff0c;配置完之后&#xff0c;我们接下来就是要执行ATP检查。本篇文章具体给大家介绍怎么来执行生产 订单ATP检查及其注意点。 执行生产订单ATP检查的…

汇编:加减乘除指令

加法指令 (ADD) ADD指令用于将两个操作数相加&#xff0c;结果存储在第一个操作数中。 语法&#xff1a; ADD destination, source 示例&#xff1a; assume cs:code ​ code segmentmov ax,3mov bx,2add ax,bx //相加&#xff0c;结果会放在ax中mov ax,4c00hint 21h co…

[C语言]自定义类型详解:结构体、联合体、枚举

目录 &#x1f680;结构体 &#x1f525;结构体类型的声明 &#x1f525;结构的自引用 &#x1f525;结构体变量的定义和初始化 &#x1f525;结构体内存对齐 &#x1f525;结构体传参 &#x1f525;结构体实现位段&#xff08;位段的填充&可移植性&#xff09; &a…