全部產品
Search
文件中心

ApsaraDB for ClickHouse:主鍵設計不合理

更新時間:Jun 17, 2025

ClickHouse的主鍵設計與傳統OLTP資料庫的B樹索引有本質區別,其核心在於通過稀疏索引和有序儲存最佳化分析查詢。本文為您介紹ClickHouse主鍵概念及最佳實務。

主鍵誤區

對於初次使用ClickHouse的使用者,經常難以完全理解其獨特的主鍵概念。通常會有以下誤區。

  • 誤區1:主鍵唯一性 ClickHouse主鍵不強制唯一,重複主鍵行也可共存,由ORDER BY子句決定資料存放區順序。

  • 誤區2:主鍵等同於索引 主鍵僅保證資料有序,過濾非首列時可能仍需掃描多資料區塊,需配合跳數索引使用。

瞭解主鍵

基礎概念理解

其實ClickHouse與基於B+Tree的OLTP資料庫不同,它使用了一個稀疏索引,該索引針對每秒插入的數百萬行和PB級資料集進行了設計。與OLTP資料庫相反,ClickHouse的索引具有以下特點。

  • 有序儲存

    資料按ORDER BY指定的主鍵順序儲存在磁碟上,每個data part內部嚴格排序,以快速識別可能匹配查詢的資料。

  • 稀疏索引

    ClickHouse的索引為稀疏索引,其以固定粒度(如每8192行)記錄主索引值,形成輕量級索引。查詢時,索引快速定位可能匹配的data part,隨後在塊內順序掃描篩選目標行。

  • 設計特點 針對海量資料插入(每秒百萬行)和PB級分析查詢最佳化,犧牲點查詢效率,換取高吞吐範圍查詢和卓越壓縮率。

通過樣本理解

結合上述基礎概念,通過一個樣本來進一步理解ClickHouse的主鍵。如下圖所示:

  1. 設計主鍵。

    1. T表主鍵設計背景:

      • 列A、B、C應該按照基數升序(低基數列在前)進行排序。基數是指列中不同值的數量。

      • 查詢使用A、B、C列頻繁過濾資料,表明這些列在查詢中為使用為頻繁的列。

    2. 建表T。

      使用DDL語句建立表T,其中指定了ORDER BY (A, B, C),列A被指定為稀疏主鍵,表T的資料將按照列A、B、C的順序進行排序。

    3. 表T資料存放區:

      • 資料在儲存中以data part形式儲存,並且這些部分是按照指定的列(A、B、C)進行排序的。

      • 每個data part都有一個稀疏主鍵,該索引基於資料的排序次序建立。

  2. 分析查詢T表,瞭解主鍵功能。

    樣本語句:SELECT ... FROM T WHERE A = ... AND B = ... AND C BETWEEN ... AND ... GROUP BY ... ORDER BY ... LIMIT ...

    ClickHouse接收到上述查詢語句後,其查詢處理引擎會根據查詢條件,使用主鍵快速定位相關資料,並通過流式讀取有序儲存的資料區塊,減少磁碟尋道時間,從而提高查詢效率。

圖片

不當主鍵影響

  • 查詢效能顯著下降。

    如果主鍵未包含高頻過濾條件列時,查詢無法利用稀疏索引快速跳過無關資料區塊,導致掃描大量冗餘資料,甚至掃描全表,進而嚴重影響了查詢效能。

  • 資料壓縮率降低。

    主鍵順序未按照基數升序排列(低基數列在前)時,相同值將分散於不同資料區塊中,導致壓縮演算法無法有效去重。

  • 合并效率低下。

    主鍵設計不合理導致資料區塊內排序混亂,合并時需處理更多重疊或片段化的資料區塊。頻繁的合併作業佔用I/O和CPU資源,也影響寫入輸送量。

主鍵選擇的關鍵原則

  • 選擇高頻過濾列

    • 列數量限制:通常不超過三列,避免索引膨脹和排序開銷。

    • 過濾頻率優先:主鍵列應為查詢中頻繁用於WHEREGROUP BYJOIN條件的列。

  • 列順序的權衡

    • 第一列最關鍵:

      對資料裁剪影響最大,應選擇高頻且高篩選率的列(如時間欄位)。

      例如,查詢通常按日期過濾,將日期作為主鍵第一列可快速跳過無關資料區塊。

    • 後續列進行壓縮最佳化:

      按列的基數升序排列(低基數列在前),提升壓縮率。

      例如,主鍵(country, city, user_id)country基數最低,相同值連續儲存壓縮效果最佳。

    • 查詢效能與壓縮的平衡:

      若高基數列需頻繁查詢,可將其前置,但可能犧牲壓縮率。

      折中方案:使用跳數索引(如bloom_filter)補充高頻但非主鍵列的查詢。但跳數索引也需設計合理,具體注意事項,請參見過度使用跳數索引

相關文檔

更多主鍵與索引的資訊,請參見主鍵和索引