ClickHouse MergeTree引擎的簡單介紹


1.介紹
Clickhouse 中最強大的表引擎當屬 MergeTree (合並樹)引擎及該系列(MergeTree)中的其他引擎。MergeTree 允許依據主鍵和日期創建索引,並進行實時的數據更新操作。MergeTree 是 ClickHouse 里最為先進的表引擎。

請注意不要將 MergeTree 跟 Merge引擎混淆!!!

MergeTree 引擎系列的基本理念如下。當你有巨量數據要插入到表中,你要高效地一批批寫入數據片段,並希望這些數據片段在后台按照一定規則合並。相比在插入時不斷修改(重寫)數據進存儲,這種策略會高效很多。

主要特點:

存儲的數據按主鍵排序。
這讓你可以創建一個用於快速檢索數據的小稀疏索引。
允許使用分區,如果指定了分區鍵的話。
在相同數據集和相同結果集的情況下 ClickHouse 中某些帶分區的操作會比普通操作更快。查詢中指定了分區鍵時 ClickHouse 會自動截取分區數據。這也有效增加了查詢性能。
支持數據副本。
ReplicatedMergeTree 系列的表便是用於此。更多信息,請參閱官方文檔。
支持數據采樣。
需要的話,你可以給表設置一個采樣方法。

不使用采樣表達式的例子:

MergeTree(EventDate, (CounterID, EventDate), 8192)*

 

使用采樣表達式的例子:
 MergeTree(EventDate, intHash32(UserID), (CounterID, EventDate, intHash32(UserID)), 8192)*

 


2. 建表

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

 MergeTree 引擎在創建時接收以下4個參數,

日期字段的名稱 (索引字段)
采樣表達式 (可選的)
含有主鍵相關字段的元組
稀疏索引的粒度(見下文)。
以 MergeTree 作為引擎的數據表必須含有一個獨立的 Date 字段。比如說, EventDate 字段。這個日期字段必須是 Date 類型的(非 DateTime 類型)。

主鍵可以是任意表達式構成的元組(通常是列名稱的元組),或者是單獨一個字段。

抽樣表達式(可選的)可以是任意表達式。這個表達式必須在主鍵中。上面的例子使用了 CounterID 的哈希 intHash32 作為采樣表達式,旨在近乎隨機地在 CounterID 和 EventDate 內打亂數據條目。換而言之,當我們在查詢中使用 SAMPLE 子句時,我們就可以得到一個近乎隨機分布的用戶列表。

數據表將數據分割為小的索引塊作為單位進行處理。 每個索引塊之間依照主鍵排序。每個索引塊記錄了指定的開始日期和結束日期。在您插入數據時,MergeTree 就會對數據進行排序處理,以保證存儲在索引塊內的數據有序。 索引塊之間的合並過程會在系統后台定期自動執行。MergeTree 引擎會選擇幾個相鄰的索引塊進行合並(通常是較小的索引塊), 然后對二者合並、排序。

具體而言, 向 MergeTree 表中插入數據時,引擎會首先對新數據執行遞增排序而保存索引塊;其后,數據索引塊之間又會進一步合並,以減少總體索引塊數量。 因此,合並過程本身並無過多排序工作。

 

3.主鍵和索引在查詢中的表現
我們以 (CounterID, Date) 以主鍵。排序好的索引的圖示會是下面這樣:

全部數據  :     [-------------------------------------------------------------------------]
CounterID:      [aaaaaaaaaaaaaaaaaabbbbcdeeeeeeeeeeeeefgggggggghhhhhhhhhiiiiiiiiikllllllll]
Date:           [1111111222222233331233211111222222333211111112122222223111112223311122333]
標記:            |      |      |      |      |      |      |      |      |      |      |
                a,1    a,2    a,3    b,3    e,2    e,3    g,1    h,2    i,1    i,3    l,3
標記號:          0      1      2      3      4      5      6      7      8      9      10

如果指定查詢如下:

CounterID in (‘a’,’h’),服務器會讀取標記號在 [0, 3) 和 [6, 8) 區間中的數據。
CounterID IN (‘a’,’h’) AND Date = 3,服務器會讀取標記號在 [1, 3) 和 [7, 8) 區間中的數據。
Date = 3,服務器會讀取標記號在 [1, 10] 區間中的數據。
上面例子可以看出使用索引通常會比全表描述要高效。

稀疏索引會引起額外的數據讀取。當讀取主鍵單個區間范圍的數據時,每個數據塊中最多會多讀 index_granularity * 2 行額外的數據。大部分情況下,當 index_granularity = 8192 時,ClickHouse的性能並不會降級。

稀疏索引讓你能操作有巨量行的表。因為這些索引是常駐內存(RAM)的。

ClickHouse 不要求主鍵惟一。所以,你可以插入多條具有相同主鍵的行。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM