
ClickHouse 是什麼:特色與一步步安裝(2026 指南)
發佈於:
閱讀時間: 5 min
主題: 技術
作者: Leandro Valencia
給獨立開發者的 ClickHouse 實踐指南:它是什麼、為什麼這麼快、關鍵特性,以及如何用 curl 或 Docker 在 5 分鐘內裝好。
目錄
ClickHouse 是什麼(不講行銷話術)
ClickHouse 是一個開源的欄式分析資料庫,用 C++ 寫成,設計目的是以「看起來像量測誤差」的速度對大資料量做彙總查詢。
關鍵詞是分析。在資料庫行話裡,這指的是 OLAP(線上分析處理),與 PostgreSQL 或 MySQL 做的 OLTP(線上交易處理)相對。
這個差別比看起來重要:
OLTP(Postgres、MySQL、SQLite) 被最佳化來非常快地讀寫單列。「給我使用者 4821」。「更新這個訂單的狀態」。每秒數千次小操作,帶交易和強一致性。
OLAP(ClickHouse、DuckDB、BigQuery) 被最佳化來讀很多列但很少欄。「給我過去 90 天按國家彙總的收入」。它不在乎某具體一列,它在乎的是掃掉數百萬列並壓成一個數。
如果你想看這個類別的完整背景——歷史、使用情境和供應商地圖——我在 OLAP 資料庫是什麼 裡展開講過。
讓它成為可能的技術關鍵是欄式儲存。一個按列的資料庫在磁碟上這樣存資料:
[id:1, país:ES, ingresos:42, timestamp:...][id:2, país:MX, ingresos:17, timestamp:...]
你要加總 ingresos 欄,就得把所有東西都讀出來,包括你並不關心的 país 和 timestamp。ClickHouse 把每一欄存到自己的檔案裡:
ingresos: [42, 17, 88, 12, ...]
país: [ES, MX, ES, AR, ...]
要加總 ingresos,你只讀這個檔案。如果你的表有 40 欄,而你的查詢用 2 欄,你只讀了 5% 的資料。魔法就是從這開始的,剩下的一切都在放大它。
為什麼這麼快:四個真正的原因
1. 殘酷的壓縮。 當你把同型別的值放在一起、而且還排好序,模式就會重複,壓縮演算法變得非常高效。ClickHouse 文件給的壓縮比,從自由文字的 2x 一路到排好序的低基數欄位的 1,000x 以上。磁碟上位元組更少 = I/O 更少 = 查詢更快。
2. 稀疏主索引。 ClickHouse 不為每列建一條 B 樹索引。它建的是稀疏索引:每 8,192 列(一個「顆粒」)一條。這意味著每 TB 資料只要幾 MB 索引,輕鬆裝進記憶體。代價是 ClickHouse 永遠不查精確的一列,而是查它所在的區塊。對分析來說,這是完全正確的取捨。
3. 向量化 + 平行引擎。 操作不是逐列執行,而是用 SIMD 指令在欄的區塊上執行。而且會積極地平行到所有可用核心。在 8 核筆電上你就感覺得到差別;在 64 核伺服器上是另一個級別。
4. 讀寫分離。 插入會建立新的「part」,在背景合併(LSM 風格的架構)。插入不阻塞查詢,查詢也不阻塞插入。
你應該知道的主要特性
這些才是真正會改變你專案設計的東西,而不是 datasheet 上的完整清單。
單一二進位、零依賴
這聽起來像個小細節,但對小專案來說很可能是最重要的一點。ClickHouse 以單一可執行檔散布,內含伺服器、用戶端和本地模式。沒有 JVM、沒有強制的 ZooKeeper、沒有編排器。你下載一個檔案,執行它,你就有一個分析資料庫。
把它和啟動 Apache Druid 對比一下——Druid 需要六種不同的行程。對單打獨鬥的獨立開發者來說,這個差別決定了專案是上線還是死在 docker-compose.yml 裡。
clickhouse-local:對檔案跑 SQL、不用起伺服器
你可以直接從磁碟或 URL 查 CSV、Parquet 或 JSON,不用匯入任何東西,也不用起伺服器:
./clickhouse local --query "
SELECT country, count() AS visitas
FROM file('logs.csv', CSVWithNames)
GROUP BY country
ORDER BY visitas DESC
LIMIT 10
"
這能取代用 pandas 寫的快速探索腳本,在大檔案上明顯更快。
增量具體化檢視
這是最改變我構建方式的一個特性。ClickHouse 的具體化檢視不是會刷新的快取:它是一個插入觸發器。每次你往源表插入,這個區塊上的彙總就被算出來、寫到目標表裡。
結果是:你把成本從查詢時刻挪到了插入時刻。你的 dashboard 查的是一張 4,000 筆的預彙總表,而不是 4 億筆的原始資料。我在進階指南裡深入講,但先把這個概念記住。
完整 SQL 支援加上真 JOIN
多年來對 ClickHouse 的標準批評是「JOIN 差」。現在已經站不住腳了。它支援所有標準 JOIN 型別,有一個用欄位統計來重排 JOIN 的最佳化器,還加了標準 SQL 裡沒有的型別,比如 ASOF JOIN(按最接近的時間點而不是精確值來連接),這對時序和金融資料是純金。
它還用數百個分析函式擴充 SQL:uniqExact、quantileTDigest、windowFunnel、sequenceMatch。在 Postgres 裡要寫 60 列 CTE 的東西,在這裡是一個函式。
相容 70+ 種格式和資料湖
它能讀寫 Parquet、Iceberg、Delta Lake、Avro、Protobuf、各種 JSON。它能直接查 S3 上的檔案而不攝入。這意味著它不會把你鎖住:哪天你想遷移,一個陳述式資料就以 Parquet 出來了。
不爆 schema 的 JSON
你可以用原生 JSON 型別攝入半結構化資料,它內部以欄式儲存。不用提前設計完美 schema 就能攝入形狀各異的事件,而仍然保有欄式資料庫的效能。
我的看法:什麼時候 ClickHouse 是對的選擇、什麼時候不是
這是大多數教學會讓你失望的地方,因為它們是想賣你東西的人寫的。
ClickHouse 是好主意,如果:
你有一張停不下來地增長的事件表——產品分析、日誌、指標、點擊、IoT 遙測——而你的查詢是對時間範圍做彙總。這是經典使用情境,也是它會像魔法的地方。
你在做面向使用者的分析:你產品裡的一個 dashboard,很多客戶同時查。ClickHouse 以毫秒級延遲處理高並發,而這正是 Snowflake 這類數倉變貴的地方。
你的 BigQuery 或 Snowflake 帳單讓你焦慮。一台每月 30-60 歐的 ClickHouse 專屬伺服器,能扛下在按用量計費的數倉上貴一個數量級的負載。對 bootstrap 的專案來說這不是最佳化,是可行和不可行的差別。
ClickHouse 是壞主意,如果:
你需要頻繁按列更新和刪除。ClickHouse 在這方面進步很大(輕量 mutation、ReplacingMergeTree、輕量刪除),但它仍然是一個為「寫一次、讀多次」設計的引擎。如果你的負載是 CRUD,用 Postgres。
你需要多表 ACID 交易。交易支援有限,而且不是專案目標。別把訂單狀態放在這裡。
你的資料少於幾百萬筆。50 萬筆的表,Postgres 加一個像樣的索引就能毫秒級回答。加 ClickHouse 是沒有收益的維運複雜度。小資料集的正確答案是不換資料庫。
你的團隊是 0 個人,而你已經要維護三個服務。這是又一個要監控、備份、升級的服務。只有效能痛點是真實的時候才值得,而不是預期中的時候。
我的實操規則:如果在你最大的表上跑一個 GROUP BY 在 Postgres 裡要超過 5 秒,而這條查詢是你產品的核心,就是時候看 ClickHouse 了。 在此之前,不要。
還有一點補充:對我最有效的模式不是取代 Postgres,而是把兩者放在一起。Postgres 繼續做交易的真相來源——使用者、訂單、設定——而 ClickHouse 透過 CDC 或複製任務接收事件表的副本。各自做各自擅長的事。
ClickHouse 一步步安裝
來點實操。根據你的需要,有三條路。
方式 1:用 curl 快速安裝(macOS、Linux、FreeBSD)
最直接的辦法。下載適合你系統的二進位:
curl https://clickhouse.com/ | sh
在 Linux 和 macOS 上,這還會把 clickhousectl(別名 chctl)裝到 ~/.local/bin,這是用來管理多個本地版本、在背景啟動伺服器、與 ClickHouse Cloud 連接的官方 CLI。
如果你只想要二進位、不要管理 CLI:
curl https://clickhouse.com/ | CLICKHOUSE_ONLY=1 sh
給 macOS 使用者的提示: 如果 Gatekeeper 抱怨無法驗證二進位的開發者,到「系統設定 → 隱私與安全性」裡批准執行。這是 macOS 對未簽章二進位的正常行為。
啟動伺服器:
./clickhouse server
在另一個終端機裡啟動用戶端:
./clickhouse client
你應該會看到類似這樣的輸出:
ClickHouse client version 24.5.1.117 (official build).
Connecting to localhost:9000 as user default.
Connected to ClickHouse server version 24.5.1.
local-host :)
資料存在當前目錄,伺服器重啟後還在。
方式 2:Docker(如果你已經在用容器,推薦)
當專案已經有 docker-compose.yml 時,這是我的預設選擇,因為它不弄髒系統、環境可重現。
docker run -d \
--name clickhouse \
-p 8123:8123 \
-p 9000:9000 \
-v clickhouse_data:/var/lib/clickhouse \
--ulimit nofile=262144:262144 \
clickhouse/clickhouse-server
這兩個連接埠很重要,一開始每箇人都搞混:
- 8123 是 HTTP 介面。大多數 Web 用戶端、BI 工具和
curl用它。 - 9000 是原生 TCP 協定。更快更精簡;
clickhouse-client和原生驅動用它。
--ulimit nofile 這個參數實際上不可省:ClickHouse 會開啟很多檔案描述符,不提高上限的話負載下會出莫名其妙的錯誤。
寫成 docker-compose.yml:
services:
clickhouse:
image: clickhouse/clickhouse-server
container_name: clickhouse
ports:
- "8123:8123"
- "9000:9000"
volumes:
- clickhouse_data:/var/lib/clickhouse
- ./config.d:/etc/clickhouse-server/config.d
ulimits:
nofile:
soft: 262144
hard: 262144
environment:
CLICKHOUSE_USER: creacosas
CLICKHOUSE_PASSWORD: cambia_esto
CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT: 1
volumes:
clickhouse_data:
連到容器裡的用戶端:
docker exec -it clickhouse clickhouse-client --user creacosas --password cambia_esto
方式 3:什麼都不裝
如果你只想試一下語法、感受速度,官方 playground 裡有已載入的真實資料集,並能在瀏覽器裡執行查詢。零摩擦。
你的第一批查詢:從零到真實資料
我們來做點接近真實情境的東西:一個網站的事件表。
建庫建表
CREATE DATABASE creacosas;
USE creacosas;
CREATE TABLE eventos
(
fecha Date,
timestamp DateTime,
usuario_id UInt32,
evento LowCardinality(String),
pais LowCardinality(String),
url String,
duracion_ms UInt32
)
ENGINE = MergeTree
PARTITION BY toYYYYMM(fecha)
ORDER BY (evento, fecha, usuario_id);
這裡有三處值得展開的決策,因為它們是ClickHouse 式的決策:
ENGINE = MergeTree 是預設表引擎,90% 的情況你都用它。整個 MergeTree 家族(ReplacingMergeTree、SummingMergeTree、AggregatingMergeTree)共享同一個底座,在 part 合併上加了額外行為。
ORDER BY 是你整個 schema 裡最重要的決策。它定義了資料在磁碟上的實體順序,預設也是主鍵。規則:把你最常用來過濾、且基數更低的欄位放前面。我們幾乎總是按事件型別和日期過濾,所以它們在前。這裡搞錯,是「ClickHouse 慢」的頭號原因。
LowCardinality(String) 是一個會做字典編碼的型別。如果一欄的不同值少於約 10,000 個(國家、事件型別、方案名),把它包進 LowCardinality 會減少儲存並明顯加速過濾。這是一個幾乎沒人一開始會用的免費收益。
插入測試資料
我們來產生 1000 萬筆合成資料,好有東西玩:
INSERT INTO eventos
SELECT
toDate('2026-01-01') + (number % 220) AS fecha,
toDateTime(fecha) + (number % 86400) AS timestamp,
(number % 50000) + 1 AS usuario_id,
['pageview','click','signup','purchase'][(intHash32(number) % 4) + 1] AS evento,
['ES','MX','AR','CO','CL','US'][(intHash32(number + 7) % 6) + 1] AS pais,
concat('/pagina/', toString(number % 500)) AS url,
(number % 5000) + 100 AS duracion_ms
FROM numbers(10000000);
numbers() 函式即時產生列:這是 ClickHouse 裡不下載任何東西就能造測試資料集的標準辦法。我對類別欄位不用 number % N 而用 intHash32(),是因為如果兩欄都用以有公因子的模數(比如 4 和 6),它們會相關,結果會人為地均勻。
查詢
SELECT
pais,
evento,
count() AS total,
round(avg(duracion_ms)) AS duracion_media,
uniqExact(usuario_id) AS usuarios_unicos
FROM eventos
WHERE fecha >= '2026-03-01'
AND evento = 'purchase'
GROUP BY pais, evento
ORDER BY total DESC;
注意用戶端輸出的最後一行。它告訴你處理了多少列、讀了多少位元組、速度是多少:
6 rows in set. Elapsed: 0.021 sec. Processed 1.14 million rows, 8.32 MB (54.28 million rows/s., 396.19 MB/s.)
那個數字——總共 1000 萬列裡的「processed 1.14 million rows」——才是關鍵。ClickHouse 只讀了表的 11%,因為 ORDER BY (evento, fecha, ...) 讓它跳過了其他所有東西。最佳化 ClickHouse 幾乎總是圍繞降低這個數字。
一個小技巧:看磁碟上的實際大小
SELECT
table,
formatReadableSize(sum(data_compressed_bytes)) AS comprimido,
formatReadableSize(sum(data_uncompressed_bytes)) AS sin_comprimir,
round(sum(data_uncompressed_bytes) / sum(data_compressed_bytes), 2) AS ratio
FROM system.columns
WHERE database = 'creacosas'
GROUP BY table;
系統表(system.columns、system.parts、system.query_log)是 ClickHouse 最讚的東西之一:引擎的全部內省都是可查詢的 SQL。
你會犯的錯(我都犯過)
一列一列地插入。 ClickHouse 討厭小插入。每次 INSERT 都在磁碟上建立一個新「part」,之後還要合併。一千次單列插入會產生一千個 part,伺服器會因 Too many parts 報錯而窒息。每次至少 1,000 筆批次插入——理想是 10,000 到 100,000——或者開啟 async_insert=1 非同步插入。
習慣性地用 Nullable。 每個 Nullable 欄位都會多加一欄遮罩、並停用一些最佳化。如果你能用哨兵值(0、空字串、1970-01-01),就用。
把高基數欄位放在 ORDER BY 第一位。 如果你把 usuario_id 或 UUID 放前面,你就破壞了壓縮和跳區塊能力。低基數在前,永遠如此。
期望 UPDATE 像 Postgres 那樣運作。 能用,但操作很重。如果你的設計依賴不斷更新列,請重新考慮設計(或重新考慮資料庫)。
結論
ClickHouse 不是通用資料庫,而這正是它的價值:它一個方向的事——對大體量做彙總——做得比幾乎所有人都好,而且以相對於其能力而言小得離譜的維運佔用做到。一個二進位、零依賴,從筆電到數百節點用同一個引擎跑。
對單打獨鬥的獨立開發者來說,最後這一點才是決定性的。你不需要一個資料團隊來維運 VPS 上的 ClickHouse。你需要的是好好理解 ORDER BY,以及不要逐列插入。
如果你是從 Postgres 過來的、dashboard 奄奄一息,那就給它一個下午。初始學習曲線是幾個小時而不是幾週,而效能躍升是那種不用量測都能感覺到的。
在本系列的下一批文章裡,我們深入裝好之後的兩個問題:
- ClickHouse 的替代方案:完整比較 —— DuckDB、StarRocks、Druid、Pinot、TimescaleDB 和雲端數倉,帶比較表和按使用情境的結論。
- ClickHouse 進階指南 —— 具體化檢視、projection、壓縮編碼、TTL、S3 分層和慢查詢診斷。
常見問題
ClickHouse 免費嗎?
引擎是 Apache 2.0 開源的,你可以無成本、無功能限制地自架。ClickHouse Cloud 是付費的託管服務,採用運算與儲存分離、按用量計費的模型,無活動時可以縮到零。
ClickHouse 能取代 PostgreSQL 嗎?
一般情況下不能。它們是幹不同活的工具:Postgres 做交易和應用狀態,ClickHouse 做分析。常見模式是兩個都用,Postgres 當真相來源,ClickHouse 接收事件資料。
多大資料量才值得?
作為實操參考,事件表從幾千萬筆開始,差別就很明顯了。少於幾百萬筆的話,索引良好的 Postgres 就夠了,維運也更簡單。
在 Windows 上能跑嗎?
可以,透過 Docker 或 WSL2,這是推薦路徑。也可以透過 clickhousectl 安裝。
該用什麼表引擎?
90% 的情況用 MergeTree。需要按鍵去重就用 ReplacingMergeTree,作為彙總具體化檢視的目標就用 SummingMergeTree 或 AggregatingMergeTree。
相關文章
繼續探索您可能感興趣的相似內容

ClickHouse 進階指南:最佳化、具體化檢視和真實技巧
如何把 ClickHouse 發揮到極致:ORDER BY、具體化檢視、projection、編碼、TTL、S3 分層和慢查詢診斷。帶真實 SQL。

OLAP 資料庫:是什麼、真實使用情境和主要供應商
OLAP 資料庫是什麼、與 OLTP 有何不同、搭配真實 SQL 的實用案例,以及 2026 年的主要供應商。

2026 年 ClickHouse 的替代方案:帶表格的誠實比較
DuckDB、StarRocks、Druid、Pinot、TimescaleDB、BigQuery 等。對 ClickHouse 替代方案的真實比較,帶表格和按使用情境的推薦。