clickhouse_mergeTree

XSWClevo發表於2024-08-13
  1. MergeTree型別
    Clickhouse 中最強大的表引擎當屬 MergeTree (合併樹)引擎及該系列(*MergeTree)中的其他引擎。

MergeTree 系列的引擎被設計用於插入極大量的資料到一張表當中。資料可以以資料片段的形式一個接著一個的快速寫入,資料片段在後臺按照一定的規則進行合併。相比在插入時不斷修改(重寫)已儲存的資料,這種策略會高效很多。

主要特點:

儲存的資料按主鍵排序。

這使得您能夠建立一個小型的稀疏索引來加快資料檢索。

如果指定了 分割槽鍵 的話,可以使用分割槽。

在相同資料集和相同結果集的情況下 ClickHouse 中某些帶分割槽的操作會比普通操作更快。查詢中指定了分割槽鍵時 ClickHouse 會自動擷取分割槽資料。這也有效增加了查詢效能。

支援資料副本。

ReplicatedMergeTree 系列的表提供了資料副本功能。更多資訊,請參閱 資料副本 一節。

支援資料取樣。

CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
    name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1] [TTL expr1],
    name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2] [TTL expr2],
    ...
    INDEX index_name1 expr1 TYPE type1(...) GRANULARITY value1,
    INDEX index_name2 expr2 TYPE type2(...) GRANULARITY value2
) ENGINE = MergeTree()
ORDER BY expr
[PARTITION BY expr]
[PRIMARY KEY expr]
[SAMPLE BY expr]
[TTL expr [DELETE|TO DISK 'xxx'|TO VOLUME 'xxx'], ...]
[SETTINGS name=value, ...]

對於以上引數的描述,可參考 CREATE 語句 的描述 。

子句

ENGINE - 引擎名和引數。 ENGINE = MergeTree(). MergeTree 引擎沒有引數。

ORDER BY — 排序鍵。

可以是一組列的元組或任意的表示式。 例如: ORDER BY (CounterID, EventDate)

如果沒有使用 PRIMARY KEY 顯式指定的主鍵,ClickHouse 會使用排序鍵作為主鍵。

如果不需要排序,可以使用 ORDER BY tuple(). 參考 選擇主鍵

PARTITION BY — 分割槽鍵 ,可選項。

大多數情況下,不需要使用分割槽鍵。即使需要使用,也不需要使用比月更細粒度的分割槽鍵。分割槽不會加快查詢(這與 ORDER BY 表示式不同)。永遠也別使用過細粒度的分割槽鍵。不要使用客戶端指定分割槽識別符號或分割槽欄位名稱來對資料進行分割槽(而是將分割槽欄位標識或名稱作為 ORDER BY 表示式的第一列來指定分割槽)。

要按月分割槽,可以使用表示式 toYYYYMM(date_column) ,這裡的 date_column 是一個 Date 型別的列。分割槽名的格式會是 "YYYYMM" 。

PRIMARY KEY - 如果要 選擇與排序鍵不同的主鍵,在這裡指定,可選項。

預設情況下主鍵跟排序鍵(由 ORDER BY 子句指定)相同。 因此,大部分情況下不需要再專門指定一個 PRIMARY KEY 子句。

SAMPLE BY - 用於抽樣的表示式,可選項。

如果要用抽樣表示式,主鍵中必須包含這個表示式。例如: SAMPLE BY intHash32(UserID) ORDER BY (CounterID, EventDate, intHash32(UserID)) 。

TTL - 指定行儲存的持續時間並定義資料片段在硬碟和捲上的移動邏輯的規則列表,可選項。

表示式中必須存在至少一個 Date 或 DateTime 型別的列,比如:

TTL date + INTERVAl 1 DAY

規則的型別 `DELETE|TO DISK 'xxx'|TO VOLUME 'xxx'``指定了當滿足條件(到達指定時間)時所要執行的動作:移除過期的行,還是將資料片段(如果資料片段中的所有行都滿足表示式的話)移動到指定的磁碟(TO DISK 'xxx') 或 卷(TO VOLUME 'xxx')。預設的規則是移除(DELETE)。可以在列表中指定多個規則,但最多隻能有一個DELETE的規則。

更多細節,請檢視 表和列的 TTL

SETTINGS — 控制 MergeTree 行為的額外引數,可選項:

index_granularity — 索引粒度。索引中相鄰的『標記』間的資料行數。預設值8192 。參考資料儲存。
index_granularity_bytes — 索引粒度,以位元組為單位,預設值: 10Mb。如果想要僅按資料行數限制索引粒度, 請設定為0(不建議)。
min_index_granularity_bytes - 允許的最小資料粒度,預設值:1024b。該選項用於防止誤操作,新增了一個非常低索引粒度的表。參考資料儲存
enable_mixed_granularity_parts — 是否啟用透過 index_granularity_bytes 控制索引粒度的大小。在19.11版本之前, 只有 index_granularity 配置能夠用於限制索引粒度的大小。當從具有很大的行(幾十上百兆位元組)的表中查詢資料時候,index_granularity_bytes 配置能夠提升ClickHouse的效能。如果您的表裡有很大的行,可以開啟這項配置來提升SELECT 查詢的效能。
use_minimalistic_part_header_in_zookeeper — ZooKeeper中資料片段儲存方式 。如果use_minimalistic_part_header_in_zookeeper=1 ,ZooKeeper 會儲存更少的資料。更多資訊參考[服務配置引數](Server Settings | ClickHouse Documentation)這章中的 設定描述 。
min_merge_bytes_to_use_direct_io — 使用直接 I/O 來操作磁碟的合併操作時要求的最小資料量。合併資料片段時,ClickHouse 會計算要被合併的所有資料的總儲存空間。如果大小超過了 min_merge_bytes_to_use_direct_io 設定的位元組數,則 ClickHouse 將使用直接 I/O 介面(O_DIRECT 選項)對磁碟讀寫。如果設定 min_merge_bytes_to_use_direct_io = 0 ,則會禁用直接 I/O。預設值:10 * 1024 * 1024 * 1024 位元組。

merge_with_ttl_timeout — TTL合併頻率的最小間隔時間,單位:秒。預設值: 86400 (1 天)。
write_final_mark — 是否啟用在資料片段尾部寫入最終索引標記。預設值: 1(不要關閉)。
merge_max_block_size — 在塊中進行合併操作時的最大行數限制。預設值:8192
storage_policy — 儲存策略。 參見 使用具有多個塊的裝置進行資料儲存.
min_bytes_for_wide_part,min_rows_for_wide_part 在資料片段中可以使用Wide格式進行儲存的最小位元組數/行數。您可以不設定、只設定一個,或全都設定。參考:資料儲存
max_parts_in_total - 所有分割槽中最大塊的數量(意義不明)
max_compress_block_size - 在資料壓縮寫入表前,未壓縮資料塊的最大大小。您可以在全域性設定中設定該值(參見max_compress_block_size)。建表時指定該值會覆蓋全域性設定。
min_compress_block_size - 在資料壓縮寫入表前,未壓縮資料塊的最小大小。您可以在全域性設定中設定該值(參見min_compress_block_size)。建表時指定該值會覆蓋全域性設定。
max_partitions_to_read - 一次查詢中可訪問的分割槽最大數。您可以在全域性設定中設定該值(參見max_partitions_to_read)。
示例配置

ENGINE MergeTree() PARTITION BY toYYYYMM(EventDate) ORDER BY (CounterID, EventDate, intHash32(UserID)) SAMPLE BY intHash32(UserID) SETTINGS index_granularity=8192

在這個例子中,我們設定了按月進行分割槽。

同時我們設定了一個按使用者 ID 雜湊的抽樣表示式。這使得您可以對該表中每個 CounterID 和 EventDate 的資料偽隨機分佈。如果您在查詢時指定了 SAMPLE 子句。 ClickHouse會返回對於使用者子集的一個均勻的偽隨機資料取樣。

index_granularity 可省略因為 8192 是預設設定 。