Map類型:ClickHouse中對動態(tài)字段的支持

背景介紹

在交互式分析場景下,很多時候除了固定字段之外沐鼠,還會有一些動態(tài)字段的需求。比如叹谁,在游戲場景下饲梭,需要動態(tài)存儲用戶每個游戲的play時長。

這種場景下焰檩,我們希望在一張表中同時存儲固定字段和動態(tài)字段的信息排拷,并且可以高效地使用動態(tài)字段做過濾查詢。

Map類型使用示例

CREATETABLEuser_game_play

(

? ??mid UInt64,

?? buvidString,

? ??game_play_durationMap(String, UInt32),

?? log_dateString

)

ENGINE=MergeTree()

PARTITION BY log_date

ORDERBYmid;?

insert into user_game_play values (1, '123',?map('王者榮耀',3600, 'FGO', 1800), '2021-11-14');

SELECT game_play_duration['王者榮耀'] AS duration?FROM test.user_game_play

┌─duration─┐

│????3600 │

└──────────┘

Map類型的取值實現(xiàn)

ClickHouse從v21.1.2.15-stable版本開始支持Map類型(詳見PR#1586)锅尘,其讀取key對應(yīng)value的實現(xiàn)邏輯大致如下:

1. 內(nèi)部用兩個數(shù)組(ColumnArray)分別存儲key和value值,我們分別稱之為 key_array和value_array布蔗。

2. 對于Map的取值操作(即map[‘key’]操作)藤违,先在從key_array中找到要找的key的下標(biāo),然后根據(jù)這個下標(biāo)到value_array里獲取對應(yīng)的值纵揍。

具體實現(xiàn)細(xì)節(jié)詳見源碼FunctionArrayElement::executeMap.

從上述分析可知,Map類型的工作方式本質(zhì)上和用兩個數(shù)組分別存儲key和value的方式是一樣的。只是在功能上做了封裝恩掷,提高了用戶使用的便捷性帚桩,但在性能上并沒有變化。

Map類型的跳數(shù)索引

索引類型

為了提升map操作的性能吧雹,我們在社區(qū)版本的Map類型基礎(chǔ)上骨杂,給其加上了多種類型的skipping

index,包括 bloom_filter 雄卷,tokenbf_v1搓蚪,ngrambf_v1

上面這三種skipping index本質(zhì)上都是用bloom filter存儲每個索引粒度的索引值。其中丁鹉,tokenbf_v1和ngrambf_v1只支持String類型妒潭,bloom_filter可支持各種類型悴能。

1. ngrambf_v1是對字符串中固定長度的substring做bloom filter存儲和檢索。

2. tokenbf_v1是對由非字母數(shù)字符號分隔開的token做bloom filter存儲和檢索雳灾。

3. bloom_filter則是直接對字段取值做bloom filter存儲和檢索漠酿。

Map類型的跳數(shù)邏輯

在數(shù)據(jù)寫入到Map類型字段時,所有的key會被抽取出來生成每個索引粒度對應(yīng)的bloom filter谎亩。

對于針對Map類型字段的過濾條件炒嘲,如:

? ??where game_play_duration[‘王者榮耀’] >= 1800 and game_play_duration[‘王者榮耀’] <=3600

會做以下處理:

1. 從filtering condition中提取map的key。

2. 分析過濾操作符(如 = , >=, <=, >, <, like , in , not in)团驱,如果該過濾條件在map不包含對應(yīng)key時不可能成立摸吠,則利用bloom filter過濾掉不可能包含對應(yīng)key的數(shù)據(jù)塊(索引粒度)。

具體實現(xiàn)細(xì)節(jié)詳見源碼PR #28634嚎花。

添加索引示例

CREATETABLEuser_game_play

(

? ??mid UInt64,

? ??buvidString,

? ??game_play_durationMap(String, UInt32),

? ??log_dateString,

? ??Index idx game_play_duration TYPE bloom_filter GRANULARITY 2,

)

ENGINE=MergeTree()

PARTITION BY log_date

ORDERBY mid;

影響跳數(shù)效果的因素

在我們的性能測試中寸痢,給Map類型添加skipping index可以收獲的性能提升差異很大。

效果好的case可以十幾到幾十倍的性能提升紊选,而效果不好的則沒有明顯提升啼止。

跳數(shù)索引的過濾效果和兩個數(shù)據(jù)特性相關(guān):

1. 索引值的cardinality:這個比較好理解,當(dāng)索引值cardinality很斜铡(比如性別献烦,可取值只有男和女),那么過濾效果通常有限卖词。

2. 索引值的分布是否聚集:ClickHouse的跳數(shù)索引和主鍵索引一樣巩那,也是稀疏索引。當(dāng)索引值分布非常離散時此蜈,即使包含查詢值的記錄占比很小即横,但可能每個數(shù)據(jù)塊(索引粒度)都包含查詢值,那么所有數(shù)據(jù)都需要讀進(jìn)內(nèi)存做過濾判斷裆赵。

Map相關(guān)函數(shù)

ClickHouse社區(qū)版本中已經(jīng)實現(xiàn)了一些map類型相關(guān)的函數(shù)东囚,包括:

1. map : 基于傳入的鍵值對生成Map類型對象。

2. mapKeys : 獲取map對象的所有keys战授。

3. mapValues : 獲取map對象的所有values

4. mapContains : 檢查map對象是否包含指定的key页藻。

更多map相關(guān)函數(shù)細(xì)節(jié)詳見這里

另外植兰,我們添加了兩個map函數(shù)mapContainsKeyLike和mapExtractKeyLike(已合并進(jìn)社區(qū)版本份帐,詳見這里) 。其中mapContainsKeyLike函數(shù)支持通過tokenbf_v1索引進(jìn)行跳數(shù)過濾钉跷。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末弥鹦,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌彬坏,老刑警劉巖朦促,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異栓始,居然都是意外死亡务冕,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進(jìn)店門幻赚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來禀忆,“玉大人,你說我怎么就攤上這事落恼÷嵬耍” “怎么了?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵佳谦,是天一觀的道長戴涝。 經(jīng)常有香客問我,道長钻蔑,這世上最難降的妖魔是什么啥刻? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮咪笑,結(jié)果婚禮上可帽,老公的妹妹穿的比我還像新娘。我一直安慰自己窗怒,他們只是感情好映跟,可當(dāng)我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著扬虚,像睡著了一般申窘。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上孔轴,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天,我揣著相機(jī)與錄音碎捺,去河邊找鬼路鹰。 笑死,一個胖子當(dāng)著我的面吹牛收厨,可吹牛的內(nèi)容都是我干的晋柱。 我是一名探鬼主播,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼诵叁,長吁一口氣:“原來是場噩夢啊……” “哼雁竞!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤碑诉,失蹤者是張志新(化名)和其女友劉穎彪腔,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體进栽,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡德挣,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了快毛。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片格嗅。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖唠帝,靈堂內(nèi)的尸體忽然破棺而出屯掖,到底是詐尸還是另有隱情,我是刑警寧澤襟衰,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布贴铜,位于F島的核電站,受9級特大地震影響右蒲,放射性物質(zhì)發(fā)生泄漏阀湿。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一瑰妄、第九天 我趴在偏房一處隱蔽的房頂上張望陷嘴。 院中可真熱鬧,春花似錦间坐、人聲如沸灾挨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽劳澄。三九已至,卻和暖如春蜈七,著一層夾襖步出監(jiān)牢的瞬間秒拔,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工飒硅, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留砂缩,地道東北人。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓三娩,卻偏偏與公主長得像庵芭,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子雀监,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容