天天看點

clickhouse之mergetree詳解

MergeTree

英文位址:https://clickhouse.yandex/docs/en/single/index.html#document-table_engines/mergetree

  MergeTree引擎提供了根據日期進行索引和根據主鍵進行索引,同時提供了實時更新資料的功能(如,在寫入資料的時候就可以對已寫入的資料進行查詢,不會阻塞。),mergetree是clickhouse裡最先進的表引擎,不要跟merge引擎混淆。

  這個引擎接受參數形式如下:日期類型的列,可選的示例表達式,一個元祖定義了這個表的主鍵,索引的間隔尺寸。

不包含示例的mergeTree:

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

包含示例的mergeTree:

MerTree(EventDate,intHash32(UserId),(CounterID,EventDate,intHash32(UserID)),8192)
           

MergeTree

  一個mergetree類型的表必須有一個包含date類型的列,在上面的例子裡,該列是EventDate,這個日期列的類型必須是'Date'(不是‘DateTime’)

  這個主鍵必須是一個元祖,元素内容通常是表裡的列或者一個單一的表達式。

  這個可選的示例可以是任何的表達式,但是這個表達式必須出現在主鍵裡.上面的示例裡使用的是一個哈希類型的userID,來僞随機的對主鍵裡的CounterID和EventDate進行打散。換句話說,當使用了這個示例列的時候,可以僞随機的将使用者打散成為均勻的子集。

  這個表是由很多個part構成。每一個part按照主鍵進行了排序,除此之外,每一個part含有一個最小日期和最大日期。當插入資料的時候,會建立一個新的sort part,同時會在背景周期性的進行merge的過程,當merge的時候,很多個part會被選中,通常是最小的一些part,然後merge成為一個大的排好序的part。

  換句話說,整個這個合并排序的過程是在資料插入表的時候進行的。這個merge會導緻這個表總是由少量的排序好的part構成,而且這個merge本身并沒有做特别多的工作。

  在插入資料的過程中,屬于不同的month的資料會被分割成不同的part,這些歸屬于不同的month的part是永遠不會merge到一起的。這麼做的目的是provide local data modification(比較容易做備份)。

  這些part在進行合并的時候會有一個大小的門檻值,是以不會有太長的merge過程。

  對于每一個part,會生成一個索引檔案。這個索引檔案存儲了表裡面每一個索引塊裡資料的主鍵的value值,換句話說,這是個對有序資料的小型索引。

  對列來說,在每一個索引塊裡的資料也寫入了标記,進而讓資料可以在明确的數值範圍内被查找到。

  當讀表裡的資料時,SELECT查詢會被轉化為要使用哪些索引。這些索引會被用在判斷where條件或者prewhere條件中,來判斷是否打中了這些索引區間。

  是以,能夠快速查詢一個或多個主鍵範圍的值。在下面的示例中,能夠快速的查詢一個明确的counter,指定範圍的日期區間裡的一個明确的counter,各種counter的集合等。

示例貼:

  所有的這些示例都是用了日期索引和主鍵。索引會被用到複雜的表達式計算中,是以讀一個組織結構化的表不會比全表掃描慢。

下面的例子中,索引不會被用到。

select count() from table where counterId = 34 or url like '%upyachka%'

  日期索引隻能讀出包含日期查詢條件的語句。然而,一個資料part可能包含很多日期的資料,在一個單一的part裡,資料是按照主鍵進行排序的,可能不會将日期作為第一列。是以,如果查詢中隻是加了日期範圍限定沒有加主鍵的限定會導緻周遊更多的資料行。

  對于同時讀和更新的表,插入操作不會阻塞讀的操作。

  讀表的行為自動就是并行化的。

  有額外的merge步驟來支援最優化的查詢。

  可以用一個很大的單表來不斷的往裡添加資料。

  資料負值在mergetree這種表引擎中也是支援的,詳細看下面的部分 ““data replication””

繼續閱讀