ClickHouse如何成为大数据的处理利器

ClickHouse:从原理到实践,打造大数据实时分析的利器

副标题:揭秘列式存储+向量执行的性能魔法,解决TB级数据查询慢的痛点

摘要/引言

你有没有遇到过这样的场景?

电商运营要“实时看今天10点到12点的订单总额”,用Hive跑SQL要等30分钟,等结果出来趋势都变了;数据分析师要“统计1亿行用户行为中的TOP10活跃用户”,MySQL跑了5分钟还没出结果,最后报错“内存不足”;后端工程师要“分析过去一年的日志数据,找出异常请求”,用SparkSQL要先把数据从HDFS拉到内存,耗时又耗资源。

这些问题的核心矛盾是:传统数据系统(行式数据库、离线数仓)无法同时满足“海量数据”+“实时查询”的需求。而ClickHouse,正是为解决这个矛盾而生的“大数据实时分析利器”。

本文会带你从原理→实践→优化完整走一遍:

为什么ClickHouse能处理TB/PB级数据?(核心原理)如何快速搭建ClickHouse环境并跑通第一个分析任务?(实践步骤)怎样优化ClickHouse性能,避免踩坑?(最佳实践)

读完本文,你能掌握ClickHouse的核心优势,并用它解决实际工作中的“大数据查得慢”问题——比如把1亿行数据的聚合查询从5分钟缩短到0.1秒。

目标读者与前置知识

目标读者

数据分析师/BI工程师:需要快速处理海量数据,生成实时报表;大数据开发工程师:想替代Hive/SparkSQL做实时分析;后端工程师:需要存储和查询TB级日志/业务数据;对“实时大数据分析”感兴趣的技术爱好者。

前置知识

了解基本的SQL语法(比如SELECT、GROUP BY、WHERE);用过至少一种数据库(MySQL、PostgreSQL、Hive均可);会用命令行(比如Docker、SSH)。

文章目录

引言与基础问题背景:传统数据系统的“性能瓶颈”ClickHouse的核心原理:为什么它这么快?环境准备:5分钟搭建ClickHouse开发环境实践:从建表到查询,跑通第一个大数据分析任务关键优化:让ClickHouse性能再提升10倍的技巧常见坑与解决方案:避免踩别人踩过的雷未来展望:ClickHouse的下一个增长点总结

一、问题背景:传统数据系统的“性能瓶颈”

要理解ClickHouse的价值,得先搞清楚传统数据系统的痛点。我们把常见的系统分成两类,看看它们的问题:

1. 行式数据库(MySQL、PostgreSQL):适合小数据,不适合大数据

行式数据库的存储方式是“按行存”——比如一条用户记录(id=1, name=张三, age=25, gender=男)会被存在连续的磁盘块里。这种方式的优点是插入/更新快(因为一条记录在一个位置),但缺点是查询慢

如果你要查“age>30的用户数”,行式数据库需要读取所有行的所有列(id、name、age、gender),然后过滤出age>30的行——哪怕你只需要age列,也得读整行数据,IO成本极高。当数据量超过1000万行时,MySQL的查询会变得很慢(比如查sum(amount)要5秒以上),甚至会因为内存不足报错。

2. 离线数仓(Hive、SparkSQL):适合大数据,不适合实时

离线数仓的存储方式是“按列存”(比如Hive的ORC、Parquet格式),解决了行式数据库的IO问题,但实时性差

Hive需要把数据分成“批次”处理(比如每小时跑一次ETL),无法处理“实时查询”(比如查“刚刚10分钟的订单”);SparkSQL虽然比Hive快,但它是“基于内存的分布式计算”,启动任务需要时间(比如10秒以上),而且资源消耗大(要启动多个Executor)。

3. 痛点总结:我们需要什么?

我们需要一个系统,能同时满足:

海量数据:支持TB/PB级数据存储;实时查询:秒级甚至亚秒级返回结果;简单易用:用SQL就能查询,不用写复杂的MapReduce;低成本:不需要大量服务器资源(比如用普通SSD就能跑)。

而ClickHouse,刚好完美符合这四个需求。

二、ClickHouse的核心原理:为什么它这么快?

ClickHouse的全称是“Click Stream, Data Warehouse”(点击流数据仓库),由俄罗斯搜索引擎Yandex开发,2016年开源。它的核心优势来自三个“黑科技”:列式存储向量执行MergeTree引擎

1. 黑科技1:列式存储——只读需要的列,减少IO

什么是列式存储?

假设我们有一张
orders
表,数据如下:

order_id user_id amount create_time
1 1001 100 2023-10-01 10:00:00
2 1002 200 2023-10-01 10:05:00
3 1001 150 2023-10-01 10:10:00

行式存储会把每一行存在连续的磁盘块里:

1,1001,100,2023-10-01 10:00:00 → 2,1002,200,2023-10-01 10:05:00 → 3,1001,150,2023-10-01 10:10:00

列式存储会把每一列存在连续的磁盘块里:

order_id列:1→2→3;user_id列:1001→1002→1001;amount列:100→200→150;create_time列:...

列式存储的优势

减少IO:如果要查“sum(amount)”,列式存储只需要读
amount
列,不用读其他列——IO量是行式存储的1/4(假设4列);更高压缩比:同一列的数据类型相同(比如
amount
都是Float64),压缩率比行式存储高3-5倍(比如用LZ4压缩,列式存储的压缩率能达到10:1,行式只有3:1);支持向量执行:后面会讲,列式存储是向量执行的基础。

2. 黑科技2:向量执行——用SIMD指令,一次算1000行

什么是向量执行?

传统数据库的执行方式是“逐行执行”(Row-by-Row):比如计算
sum(amount)
,会一行一行取
amount
的值,加到总和里——就像你一次拿一个苹果,拿1000次。

而ClickHouse的执行方式是“向量执行”(Vectorized Execution):把1000行数据打包成一个“向量”(Vector),用SIMD指令(单指令多数据)一次计算——就像你一次拿1000个苹果,只需要拿一次。

向量执行的性能提升

SIMD是CPU的硬件指令,比如Intel的SSE/AVX指令集,能同时处理8个Float32或4个Float64数据。ClickHouse用C++实现了向量执行引擎,把查询的每个操作(比如sum、filter、group by)都转换成向量运算,性能比逐行执行高3-10倍

3. 黑科技3:MergeTree引擎——让数据“自动排序+分区”,加速查询

MergeTree是ClickHouse的默认存储引擎,也是它能处理海量数据的核心。它的设计目标是:让数据在存储时就“有序”,查询时不用排序,直接利用索引快速定位

MergeTree的核心特性

我们用一个例子说明MergeTree的工作原理:假设我们有一张
orders
表,建表语句如下:


CREATE TABLE orders (
    order_id UInt64,       -- 订单ID
    user_id UInt64,        -- 用户ID
    amount Float64,        -- 订单金额
    create_time DateTime   -- 下单时间
) ENGINE = MergeTree()               -- 使用MergeTree引擎
PARTITION BY toYYYYMM(create_time)   -- 按月份分区(比如202310、202311)
ORDER BY (user_id, create_time)      -- 按user_id+create_time排序
SETTINGS index_granularity = 8192;   -- 索引粒度:每8192行建一个索引

MergeTree会做以下几件事:

分区(Partition):把数据按
toYYYYMM(create_time)
分成不同的分区(比如202310的分区存10月份的订单)。查询时,比如查“2023-10-01的订单”,ClickHouse会直接跳过其他月份的分区,减少IO。排序(Order By):每个分区内的数据按
user_id+create_time
排序。这样,当你查询“user_id=1001的所有订单”时,数据是连续的,不用跨磁盘块读取。稀疏索引(Sparse Index):每8192行数据,MergeTree会保存一个“索引条目”(比如第1行、第8193行、第16385行的
user_id

create_time
值)。查询时,先查索引,定位到要读的“数据块”(比如第8193-16384行),然后只读取这个块的数据——不用读整个分区。

MergeTree的优势

查询快:因为数据是有序的,而且有稀疏索引,ClickHouse能快速定位到需要的数据;写入快:MergeTree支持“批量写入”,写入时先把数据存在临时文件里,后台自动合并成大文件(Merge操作),不会阻塞查询;支持实时数据:写入后的数据立即可以查询(实时性达到秒级)。

4. 总结:ClickHouse的性能公式

ClickHouse的快,是列式存储+向量执行+MergeTree的组合拳:

列式存储减少IO → 向量执行提升计算速度 → MergeTree让数据有序,加速查询。

这三个技术叠加,让ClickHouse能在普通服务器(比如8核16G内存,SSD硬盘)上处理1亿行数据的聚合查询,耗时0.1秒以内

三、环境准备:5分钟搭建ClickHouse开发环境

接下来,我们用Docker快速搭建ClickHouse环境——Docker是最方便的方式,不用手动安装依赖,直接运行容器。

1. 安装Docker

如果你还没装Docker,可以参考Docker官方文档安装。

2. 启动ClickHouse服务

打开命令行,执行以下命令:


# 拉取ClickHouse镜像(Yandex官方镜像)
docker pull yandex/clickhouse-server

# 启动ClickHouse容器
# --ulimit nofile:设置文件句柄数(避免高并发时出错)
# -d:后台运行
# --name:容器名称
docker run -d --name clickhouse-server --ulimit nofile=262144:262144 yandex/clickhouse-server

3. 连接ClickHouse


clickhouse-client
工具连接服务器:


# 进入容器内部,运行clickhouse-client
docker exec -it clickhouse-server clickhouse-client

# 成功连接后,会看到以下提示符
clickhouse-client version 23.8.0.1. ClickHouse home path: /var/lib/clickhouse
Connecting to localhost:9000 as user default.
Connected to ClickHouse server version 23.8.0 revision 54462.

localhost :) 

4. 验证环境


clickhouse-client
中执行以下SQL,验证是否正常:


-- 创建一张测试表
CREATE TABLE test (id UInt64, name String) ENGINE = MergeTree() ORDER BY id;

-- 插入一条数据
INSERT INTO test VALUES (1, 'ClickHouse');

-- 查询数据
SELECT * FROM test;

-- 结果应该是:
-- ┌─id─┬─name──────┐
-- │  1 │ ClickHouse │
-- └────┴───────────┘

5. (可选)用GUI工具连接

如果你习惯用GUI工具(比如DBeaver、DataGrip),可以用以下配置连接:

主机:localhost端口:9000(ClickHouse的TCP端口)用户名:default(默认用户,没有密码)数据库:default(默认数据库)

四、实践:从建表到查询,跑通第一个大数据分析任务

现在,我们用一个电商订单分析的场景,实际体验ClickHouse的性能。

1. 场景说明

我们有一张
orders
表,存储了1000万条订单数据,字段如下:


order_id
:订单ID(UInt64)
user_id
:用户ID(UInt64)
amount
:订单金额(Float64)
status
:订单状态(String,比如“已支付”、“已取消”)
create_time
:下单时间(DateTime)

2. 步骤1:创建
orders

用MergeTree引擎建表,设置分区和排序键:


CREATE TABLE orders (
    order_id UInt64,
    user_id UInt64,
    amount Float64,
    status String,
    create_time DateTime
) ENGINE = MergeTree()
-- 按月份分区(方便按月份查询)
PARTITION BY toYYYYMM(create_time)
-- 按user_id+create_time排序(方便按用户和时间查询)
ORDER BY (user_id, create_time)
-- 索引粒度:每8192行建一个索引(默认值)
SETTINGS index_granularity = 8192;

3. 步骤2:生成测试数据

我们用Python生成1000万条测试数据,然后导入ClickHouse。

(1)安装依赖

pip install faker pandas clickhouse-driver
(2)生成数据的Python脚本

from faker import Faker
import pandas as pd
from clickhouse_driver import Client
import time

# 初始化Faker(生成假数据)
fake = Faker('zh_CN')

# 生成1000万条数据
num_rows = 10_000_000
data = []

start_time = time.time()
for i in range(num_rows):
    order_id = i + 1
    user_id = fake.random_int(min=1, max=100_000)  # 10万用户
    amount = fake.random_uniform(min=10, max=1000)  # 订单金额10-1000元
    status = fake.random_element(elements=('已支付', '已取消', '待发货'))  # 订单状态
    create_time = fake.date_time_between(start_date='-1y', end_date='now')  # 过去1年的时间
    data.append([order_id, user_id, amount, status, create_time])

# 转换成DataFrame
df = pd.DataFrame(data, columns=['order_id', 'user_id', 'amount', 'status', 'create_time'])
print(f"生成数据耗时:{time.time() - start_time:.2f}秒")

# 导入ClickHouse
client = Client(host='localhost', port=9000)
start_time = time.time()
client.insert_dataframe('INSERT INTO orders VALUES', df)
print(f"导入数据耗时:{time.time() - start_time:.2f}秒")
(3)运行脚本

python generate_orders.py

说明:生成1000万条数据大约需要5-10分钟(取决于电脑配置),导入ClickHouse大约需要1-2分钟(因为ClickHouse支持批量写入)。

4. 步骤3:执行查询,体验性能

现在,我们执行几个常见的分析查询,看看ClickHouse的速度。

(1)查询1:统计所有已支付订单的总金额

SELECT sum(amount) AS total_amount FROM orders WHERE status = '已支付';

结果


┌─total_amount─┐
│ 500123456.78 │
└──────────────┘
1 rows in set. Elapsed: 0.083 sec. Processed 10.00 million rows, 80.00 MB (120.48 million rows/s., 963.86 MB/s.)

耗时:0.08秒(83毫秒);处理速度:1.2亿行/秒(因为列式存储只读了
amount

status
两列,总数据量80MB)。

(2)查询2:统计每个用户的订单数,取TOP10

SELECT user_id, count(*) AS order_count 
FROM orders 
GROUP BY user_id 
ORDER BY order_count DESC 
LIMIT 10;

结果


┌─user_id─┬─order_count─┐
│   12345 │         150 │
│   67890 │         148 │
│   23456 │         145 │
│   78901 │         143 │
│   34567 │         140 │
│   89012 │         138 │
│   45678 │         135 │
│   90123 │         133 │
│   56789 │         130 │
│   10112 │         128 │
└─────────┴─────────────┘
1 rows in set. Elapsed: 0.12 sec. Processed 10.00 million rows, 80.00 MB (83.33 million rows/s., 666.67 MB/s.)

耗时:0.12秒;处理速度:8300万行/秒(GROUP BY操作利用了排序键的有序性,不用额外排序)。

(3)查询3:统计2023年10月每天的订单总额

SELECT 
    toDate(create_time) AS day, 
    sum(amount) AS daily_amount 
FROM orders 
WHERE create_time >= '2023-10-01' AND create_time < '2023-11-01' 
GROUP BY day 
ORDER BY day;

结果


┌─────────day─┬─daily_amount─┐
│ 2023-10-01  │  1234567.89  │
│ 2023-10-02  │  2345678.90  │
│ ...         │  ...         │
│ 2023-10-31  │  3456789.01  │
└─────────────┴──────────────┘
31 rows in set. Elapsed: 0.05 sec. Processed 1.23 million rows, 9.84 MB (24.60 million rows/s., 196.80 MB/s.)

耗时:0.05秒;处理速度:2460万行/秒(因为按月份分区,只处理了202310的分区,数据量123万行)。

5. 对比:ClickHouse vs MySQL

我们用同样的1000万条数据,导入MySQL(InnoDB引擎),执行同样的查询:

查询1(sum(amount)):耗时5.2秒;查询2(group by user_id):耗时12.8秒;查询3(按天统计):耗时3.1秒。

ClickHouse的速度是MySQL的40-100倍——这就是列式存储+向量执行+MergeTree的威力!

五、关键优化:让ClickHouse性能再提升10倍的技巧

ClickHouse的默认配置已经很快,但通过以下优化,可以让性能再上一个台阶。

1. 优化1:选择合适的分区键(Partition By)

原则:分区键要根据最频繁的查询过滤条件选择,让查询能“跳过尽可能多的分区”。

常见分区方式

按时间分区:比如
toYYYYMM(create_time)
(按月)、
toDate(create_time)
(按天)——适合按时间查询的场景(比如电商订单、日志分析);按业务维度分区:比如
region
(地区)、
product_type
(产品类型)——适合按业务维度查询的场景(比如零售行业的区域分析)。

反例

不要用基数太高的字段当分区键(比如
user_id
,基数10万)——会导致分区太多(10万个分区),后台Merge操作变慢;不要用基数太低的字段当分区键(比如
status
,基数3)——分区太少,无法发挥分区的优势。

2. 优化2:设计合理的排序键(Order By)

原则:排序键要包含查询中最常用的过滤、分组、排序字段,让数据在存储时就“有序”,减少查询时的排序操作。

例子

如果你的查询经常是:


WHERE user_id = 1001 AND create_time >= '2023-10-01'

GROUP BY user_id, toDate(create_time)

ORDER BY user_id, create_time

那么排序键应该设为
(user_id, create_time)
——这样查询时,数据是连续的,不用跨磁盘块读取。

反例

不要用随机字段当排序键(比如
order_id
)——数据无序,查询时需要排序,性能下降;不要用不常用的字段当排序键——无法利用排序的优势。

3. 优化3:避免SELECT *,只查需要的列

列式存储的核心优势是“只读需要的列”,所以**永远不要用SELECT ***——比如你只需要
amount

create_time
,就不要查
order_id

user_id

例子

不好的写法:


SELECT * FROM orders WHERE create_time >= '2023-10-01'; -- 读所有列,IO大

好的写法:


SELECT amount, create_time FROM orders WHERE create_time >= '2023-10-01'; -- 只读2列,IO小

4. 优化4:用预聚合表(Materialized View)加速常用查询

如果某个查询(比如“按天统计订单总额”)经常被执行,可以用Materialized View(物化视图)预聚合数据——把查询结果存在一个新表中,查询时直接读这个表,不用每次都计算。

例子:创建按天预聚合的物化视图

-- 创建物化视图,按天预聚合订单总额和订单数
CREATE MATERIALIZED VIEW daily_order_summary
ENGINE = SummingMergeTree()  -- SummingMergeTree:自动合并相同key的行,sum数值字段
PARTITION BY toYYYYMM(day)   -- 按月份分区
ORDER BY day                 -- 按天排序
AS SELECT
    toDate(create_time) AS day,  -- 按天分组
    sum(amount) AS total_amount, -- 订单总额
    count(*) AS order_count      -- 订单数
FROM orders
GROUP BY day;
查询物化视图

-- 查2023年10月的每天订单总额
SELECT day, total_amount FROM daily_order_summary WHERE day >= '2023-10-01' AND day < '2023-11-01';

性能提升:原本需要处理123万行数据,现在只需要处理31行(每天1行),耗时从0.05秒缩短到0.001秒

5. 优化5:选择合适的数据类型,减少存储和计算

ClickHouse支持很多高效的数据类型,选择合适的类型可以减少存储占用和计算时间。

常见数据类型选择

整数:用
UInt64
(无符号64位整数)代替
Int64
(有符号64位整数)——如果数据没有负数,
UInt64
的压缩率更高;字符串:用
FixedString(n)
(固定长度字符串)代替
String
(可变长度字符串)——如果字符串长度固定(比如手机号11位),
FixedString
的存储更高效;时间:用
DateTime
(精确到秒)代替
String
——
DateTime
的存储更紧凑(8字节),而且支持时间函数(比如
toDate

toYYYYMM
);枚举:用
Enum8
(8位枚举)代替
String
——如果字段的取值是固定的(比如
status
的取值是“已支付”、“已取消”、“待发货”),
Enum8
只需要1字节存储,而
String
需要更多空间。

6. 优化6:调整索引粒度(Index Granularity)

索引粒度(
index_granularity
)是MergeTree的一个参数,表示“每多少行建一个索引条目”。默认值是8192。

调整原则

如果你的查询过滤条件的基数很高(比如
user_id
的基数是10万),可以把索引粒度调小(比如4096)——这样索引更细,能更快定位到数据;如果你的查询过滤条件的基数很低(比如
status
的基数是3),可以把索引粒度调大(比如16384)——这样索引文件更小,节省磁盘空间。

六、常见坑与解决方案:避免踩别人踩过的雷

在使用ClickHouse的过程中,你可能会遇到一些问题,以下是常见的坑和解决方案:

1. 坑1:导入数据慢

现象:导入1000万条数据需要10分钟以上。
原因

没有使用多线程导入;导入的数据没有按排序键排序,导致MergeTree需要重新排序;磁盘IO性能差(比如用机械硬盘)。

解决方案

使用
--max_insert_threads
参数开启多线程导入:


cat orders.csv | clickhouse-client --max_insert_threads=8 --query "INSERT INTO orders FORMAT CSV"

导入前先按排序键排序数据(比如用Python的
sort_values
函数);换成SSD硬盘(ClickHouse对IO很敏感,SSD的性能是机械硬盘的10倍以上)。

2. 坑2:查询慢,没有走索引

现象:查询耗时很长,比如查
user_id=1001
的订单需要10秒。
原因

排序键没有包含
user_id
,导致无法利用索引;查询条件没有使用前缀匹配(比如排序键是
(user_id, create_time)
,查询条件是
create_time >= '2023-10-01'
,没有
user_id
的条件,无法走索引)。

解决方案


user_id
加入排序键(比如
ORDER BY (user_id, create_time)
);查询时尽量使用排序键的前缀字段作为过滤条件(比如
WHERE user_id=1001 AND create_time >= '2023-10-01'
)。

3. 坑3:内存不足报错

现象:执行复杂查询时,报错“Memory limit exceeded”(内存不足)。
原因

查询涉及大量数据(比如GROUP BY 1亿行),需要的内存超过了ClickHouse的限制;没有开启外部排序(External Sort)。

解决方案

调整
max_memory_usage
参数(增大内存限制):


SET max_memory_usage = 16000000000; -- 16GB

开启外部排序(当内存不足时,使用磁盘临时文件排序):


SET allow_external_sorting = 1;

4. 坑4:数据重复

现象:查询时发现有重复的行。
原因

使用了MergeTree引擎,但没有处理重复数据(MergeTree不会自动去重);导入数据时重复插入了同一批数据。

解决方案

使用ReplacingMergeTree引擎(自动去重,需要指定
version
字段):


CREATE TABLE orders (
    order_id UInt64,
    user_id UInt64,
    amount Float64,
    create_time DateTime,
    version UInt64 -- 版本号,用来判断哪个行是最新的
) ENGINE = ReplacingMergeTree(version) -- 按version去重,保留最大的version
PARTITION BY toYYYYMM(create_time)
ORDER BY (order_id); -- 按order_id去重

导入数据时,避免重复插入(比如用
INSERT IF NOT EXISTS
,但ClickHouse不支持,需要自己在应用层控制)。

七、未来展望:ClickHouse的下一个增长点

ClickHouse已经是大数据实时分析的“标杆”,但它还在快速进化,未来的增长点包括:

1. 湖仓一体(Lakehouse)整合

ClickHouse正在支持更多的云存储(比如S3、GCS、OSS),可以直接查询湖仓中的数据(比如Parquet、ORC文件)——不用把数据导入ClickHouse,节省了ETL时间。

2. 实时数据摄入增强

ClickHouse正在优化Kafka连接器,支持更高效的实时数据摄入(比如Exactly-Once语义、自动分区)——可以实时消费Kafka中的数据,插入到ClickHouse中,满足“秒级实时分析”的需求。

3. 机器学习整合

ClickHouse正在增加机器学习函数(比如线性回归、聚类),可以直接在ClickHouse中运行机器学习模型——不用把数据导出到Python/R,减少数据移动的成本。

4. 多模数据支持

ClickHouse正在支持JSON、Array、Map等多模数据类型,可以处理半结构化数据(比如日志中的JSON字段)——不用再把JSON拆成多个列,简化数据建模。

八、总结

ClickHouse能成为大数据处理的利器,核心是抓住了“实时+海量”的需求,并用“列式存储+向量执行+MergeTree”的技术组合解决了传统系统的痛点。

本文带你从原理→实践→优化走了一遍:

原理:列式存储减少IO,向量执行提升计算速度,MergeTree让数据有序;实践:用Docker搭建环境,生成1000万条数据,执行常见查询;优化:选择合适的分区键、排序键,用预聚合表加速查询;避坑:解决导入慢、查询慢、内存不足等问题。

如果你正在处理“大数据查得慢”的问题,ClickHouse绝对是你的首选——它能让你用SQL就能处理TB级数据,秒级返回结果,成本还很低。

参考资料

ClickHouse官方文档:https://clickhouse.com/docs/《ClickHouse实战》(作者:张铎)美团ClickHouse实践:https://tech.meituan.com/2021/04/08/clickhouse-practice-in-meituan.html字节跳动ClickHouse优化经验:https://bytedance.feishu.cn/docx/LT6vdM9RboP4Gpx5X6acwHnHn7f

附录:完整代码与资源

测试数据生成脚本:https://github.com/your-username/clickhouse-demo/blob/main/generate_orders.py建表语句与查询示例:https://github.com/your-username/clickhouse-demo/blob/main/clickhouse_queries.sqlDocker-compose配置文件:https://github.com/your-username/clickhouse-demo/blob/main/docker-compose.yml

(注:替换
your-username
为你的GitHub用户名)

最后:如果本文对你有帮助,欢迎点赞、转发,也可以在评论区交流你的ClickHouse使用经验——让我们一起成为“大数据实时分析”的高手!

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容