文章目錄
ClickHouse 在彙總資料時的效能優勢
前提:雖然本篇筆記中使用了 MySql 做為範例,但主要是因為目前團隊使用 MySql,我對 MySql 相同熟悉點,而不是為了踩 MySql 捧 ClickHouse,而是為了突顯在不同目的與情境下,選擇更適合的技術會比 performance tuning 更有效率
一般系統在正常運作下,不免會有將資料彙總這類報表的需求,例如:統計每個月的銷售量、每個月的訂單數量、每個月的訂單金額等等,這時候就會需要用到 group by
這個語法,這類查詢方式很容易讓傳統 OLTP 以 row 為儲存基準的 DB 陷入效能瓶頸,本篇筆記就是要呈現 ClickHouse 在彙總資料時的效能優勢
本篇筆記用到基本環境,詳細內容可以參考之前筆記 C# 如何新增資料至 ClickHouse 與 C# 如何快速新增大量資料至 MySQL
基本環境說明
- macOS Sonoma 14.2.1 (Apple M2 Pro)
- OrbStack Version 1.2.0 (16496)
- .NET SDK 8.0.100
- JetBrains Rider 2023.3.2
Container Images
- clickhouse/clickhouse-server:23.11.3.23
- mysql:8.2
NuGet Library
- Bogus 35.3.0
- BenchmarkDotNet 0.13.11
- ClickHouse.Ado 2.0.2.2
- ClickHouse.Client 6.8.1
- MySqlConnector 2.3.3
- CsvHelper 30.0.1
docker-compose.yml
ClickHouse DDL
MySql DDL
測試資料
產生一億筆資料
實際比較
情境說明
以 OrderType 分組,計算每個 OrderType 的總金額
select order_type,sum(amount) from test.orders group by order_type;
以 ProductId 分組,計算每個 ProductId 的總金額
select product_id,sum(amount) from test.orders group by product_id;
指定 OrderDate 區間計算總金額
SELECT sum(amount) FROM test.orders WHERE order_date BETWEEN '2023-11-01' AND '2023-11-30';
指定 OrderDate 區間計算總金額,並以 OrderType 分組
SELECT order_type, sum(amount) FROM test.orders WHERE order_date BETWEEN '2022-04-01' AND '2022-04-30' GROUP BY order_type;
效能比較
程式碼
比較結果
心得
- ClickHouse 與 MySql 彙總出來的金額有落差,我快速確認過較小的資料就有這個傾向,看起來是對於小數點後的資料處理方式不同,但這不是本篇筆記的重點,所以就不深入研究了,但如果後續要實際應用還是需要解決,畢竟錢的問題不能含糊
- 不管是 ClickHouse 或是 MySql 在 table 的定義、index 的調整或是 table engine 的選擇,甚至是 query script 的寫法上都有不小優化空間,但還是想用這個例子來呈現不同技術在相同情境下的效能差異
- 單就本筆記的簡單範例看來,相同查詢在 ClickHouse 與 MySql 有接近 200 倍的效能差異
完整程式碼可以參考 GitHub:yowko/ClickHouseMySqlQueryBenchmark
參考資訊
文章作者 Yowko Tsai
上次更新 2024-01-03
授權合約
本部落格 (Yowko's Notes) 所有的文章內容(包含圖片),任何轉載行為,必須通知並獲本部落格作者 (Yowko Tsai) 的同意始得轉載,且轉載皆須註明出處與作者。
Yowko's Notes 由 Yowko Tsai 製作,以創用CC 姓名標示-非商業性-相同方式分享 3.0 台灣 授權條款 釋出。