clickhouse 21.x生產(chǎn)實(shí)踐優(yōu)化

clickhouse
1 時(shí)間字段類型
  • 建表時(shí)能用數(shù)值型或日期時(shí)間型表示的字段就不要用字符串,全String 類型在以Hive(hbase)為中心的數(shù)倉(cāng)建設(shè)中常見扁远,但 ClickHouse 環(huán)境不應(yīng)受此影響敬辣。雖然 ClickHouse 底層將DateTime 存儲(chǔ)為時(shí)間戳Long類型称勋,但不建議存儲(chǔ)Long 類型耀鸦,因?yàn)镈ateTime 不需要經(jīng)過函數(shù)轉(zhuǎn)換處理捶枢,執(zhí)行效率高稀拐、可讀性好火邓。
2 Nullable類型
  • 官方已經(jīng)指出Nullable 類型幾乎總是會(huì)拖累性能,因?yàn)榇鎯?chǔ)Nullable 列時(shí)需要?jiǎng)?chuàng)建一個(gè)額外的文件來存儲(chǔ) NULL 的標(biāo)記德撬,并且 Nullable 列無法被索引铲咨。因此除非極特殊情況,應(yīng)直接使用字段默認(rèn)值表示空蜓洪,或者自行指定一個(gè)在業(yè)務(wù)中無意義的值(例如用-1 表示沒有商品ID)
3 分區(qū)與索引
  • 一般選擇按天分區(qū)纤勒,也可以指定為 Tuple(),以單表一億數(shù)據(jù)為例隆檀,分區(qū)大小控制在 10-30 個(gè)為最佳摇天。

  • 必須指定索引列粹湃,ClickHouse 中的索引列即排序列,通過 order by 指定泉坐,一般在查詢條件中經(jīng)常被用來充當(dāng)篩選條件的屬性被納入進(jìn)來为鳄;可以是單一維度,也可以是組合維度的索引腕让;通常需要滿足高級(jí)列在前济赎、查詢頻率大的在前原則;還有基數(shù)特別大的不適合做索引列记某,如用戶表的 userid 字段司训;通常篩選后的數(shù)據(jù)滿足在百萬以內(nèi)為最佳。

4 數(shù)據(jù)TTL
  • 如果表中不是必須保留全量歷史數(shù)據(jù)液南,建議指定 TTL(生存時(shí)間值)壳猜,可以免去手動(dòng)過期歷史數(shù)據(jù)的麻煩,TTL 也可以通過 alter table 語句隨時(shí)修改滑凉。
5 寫入與刪除優(yōu)化
  • 盡量不要執(zhí)行單條或小批量刪除和插入操作统扳,這樣會(huì)產(chǎn)生小分區(qū)文件,給后臺(tái)Merge 任務(wù)帶來巨大壓力

  • 不要一次寫入太多分區(qū)畅姊,或數(shù)據(jù)寫入太快咒钟,數(shù)據(jù)寫入太快會(huì)導(dǎo)致 Merge 速度跟不上而報(bào)錯(cuò),一般建議每秒鐘發(fā)起 2-3 次寫入操作若未,每次操作寫入 2w~5w 條數(shù)據(jù)(依服務(wù)器性能而定)

  • Too many parts錯(cuò)誤:in_memory_parts_enable_wal 默認(rèn)為 true(開啟wal預(yù)寫日志)

  • Memory limit錯(cuò)誤:增加內(nèi)存設(shè)置max_memory_usage 朱嘴,或者內(nèi)存不充裕建議將超出部分內(nèi)容分配到系統(tǒng)硬盤上max_bytes_before_external_group_by、max_bytes_before_external_sort

6 謂詞下推:(各個(gè)版本性能損失有差異)
  • 當(dāng) group by 有 having 子句粗合,但是沒有 with cube萍嬉、with rollup 或者 with totals 修飾的時(shí)候,having 過濾會(huì)下推到 where 提前過濾隙疚。例如下面的查詢壤追,HAVING name 變成了 WHERE name,在 group by 之前過濾
7 Prewhere替代where
  • 當(dāng)查詢列明顯多于篩選列時(shí)使用 Prewhere 可十倍提升查詢性能供屉,Prewhere 會(huì)自動(dòng)優(yōu)化執(zhí)行過濾階段的數(shù)據(jù)讀取方式行冰,降低 io 操作
  • 默認(rèn):Prewhere自動(dòng)打開,但是某些場(chǎng)景即使開啟優(yōu)化伶丐,也不會(huì)自動(dòng)轉(zhuǎn)換成 prewhere悼做,需要手動(dòng)指定 prewhere:
    1)使用常量表達(dá)式
    2)使用默認(rèn)值為 alias 類型的字段
    3)包含了 arrayJOIN,globalIn撵割,globalNotIn 或者 indexHint 的查詢
    4)select 查詢的列字段和 where 的謂詞相同
    5)使用了主鍵字段
8 類關(guān)系型數(shù)據(jù)庫(kù)要求
  • 千萬以上數(shù)據(jù)集進(jìn)行 order by 查詢時(shí)需要搭配 where 條件和 limit 語句一起使用(mysql贿堰、oracle也有同樣的要求)
9 避免構(gòu)建虛擬列
  • 其實(shí)就是mysql、oracle要求使用函數(shù)的列不會(huì)命中索引
SELECT Income,Age,Income/Age as IncRate FROM datasets.hits_v1;
10 uniqCombined 替代distinct
  • 性能可提升10 倍以上啡彬,uniqCombined 底層采用類似HyperLogLog 算法實(shí)現(xiàn)羹与,能接收2%左右的數(shù)據(jù)誤差故硅,可直接使用這種去重方式提升查詢性能。Count(distinct )會(huì)使用uniqExact精確去重纵搁。不建議在千萬級(jí)不同數(shù)據(jù)上執(zhí)行 distinct 去重查詢吃衅,改為近似去重uniqCombined
反例:select count(distinct rand()) from hits_v1;

正例:SELECT uniqCombined(rand()) from datasets.hits_v1
11 用IN代替JOIN
  • mysql、oracle exist輪訓(xùn)外表腾誉,子查詢是大表徘层;in用于子查詢是小表
  • 當(dāng)多表聯(lián)查時(shí),查詢的數(shù)據(jù)僅從其中一張表出時(shí)利职,可考慮用 IN 操作而不是 JOIN
12 大小表JOIN(mysql趣效、oracle通用要求)
  • 多表 join 時(shí)要滿足小表在右的原則,右表關(guān)聯(lián)時(shí)被加載到內(nèi)存中與左表進(jìn)行比較猪贪,ClickHouse 中無論是 Left join 跷敬、Right join 還是 Inner join 永遠(yuǎn)都是拿著右表中的每一條記錄到左表中查找該記錄是否存在,所以右表必須是小表热押。
13 分布式表使用GLOBAL
  • 兩張分布式表上的 IN 和 JOIN 之前必須加上 GLOBAL 關(guān)鍵字西傀,右表只會(huì)在接收查詢請(qǐng)求的那個(gè)節(jié)點(diǎn)查詢一次,并將其分發(fā)到其他節(jié)點(diǎn)上桶癣。如果不加 GLOBAL 關(guān)鍵字的話拥褂,每個(gè)節(jié)點(diǎn)都會(huì)單獨(dú)發(fā)起一次對(duì)右表的查詢,而右表又是分布式表牙寞,就導(dǎo)致右表一共會(huì)被查詢 N2次(N是該分布式表的分片數(shù)量)饺鹃,這就是查詢放大,會(huì)帶來很大開銷碎税。
14 數(shù)據(jù)一致性
  • 即便對(duì)數(shù)據(jù)一致性支持最好的 Mergetree尤慰,也只是保證最終一致性,ReplacingMergeTree去重時(shí)機(jī)不確定性
    1)在查詢語句后增加 FINAL 修飾符雷蹂,這樣在查詢的過程中將會(huì)執(zhí)行Merge 的特殊邏輯(例如數(shù)據(jù)去重,預(yù)聚合等)
    2)在 v20.5.2.7-stable 版本及以后杯道,F(xiàn)INAL 查詢支持多線程執(zhí)行匪煌,并且可以通過max_final_threads參數(shù)控制單個(gè)查詢的線程數(shù)。
explain pipeline select * from visits_v1 final WHERE StartDate = '2014-03-17' limit 100 settings max_final_threads = 2;

(Expression)

ExpressionTransform × 2

(SettingQuotaAndLimits)

(Limit)

Limit 2 → 2

(ReadFromMergeTree)

ExpressionTransform × 2

CollapsingSortedTransform × 2

Copy 1 → 2

AddingSelector

ExpressionTransform

MergeTree 0 → 1

從 CollapsingSortedTransform 這一步開始已經(jīng)是多線程執(zhí)行党巾,但是讀取 part 部分的動(dòng)作還是串行
15 物化視圖:
1)定義:
  • 普通視圖不保存數(shù)據(jù)萎庭,保存的僅僅是查詢語句,查詢的時(shí)候還是從原表讀取數(shù)據(jù)齿拂,可以將普通視圖理解為是個(gè)子查詢驳规。物化視圖則是把查詢的結(jié)果根據(jù)相應(yīng)的引擎存入到了磁盤或內(nèi)存中,對(duì)數(shù)據(jù)重新進(jìn)行了組織署海,你可以理解物化視圖是完全的一張新表吗购。
2)優(yōu)缺點(diǎn)
  • 優(yōu)點(diǎn):查詢速度快医男,要是把物化視圖這些規(guī)則全部寫好,它比原數(shù)據(jù)查詢快了很多捻勉,總的行數(shù)少了镀梭,因?yàn)槎碱A(yù)計(jì)算好了。

  • 缺點(diǎn):它的本質(zhì)是一個(gè)流式數(shù)據(jù)的使用場(chǎng)景踱启,是累加式的技術(shù)报账,所以要用歷史數(shù)據(jù)做去重、去核這樣的分析埠偿,在物化視圖里面是不太好用的透罢。在某些場(chǎng)景的使用也是有限的。而且如果一張表加了好多物化視圖冠蒋,在寫這張表的時(shí)候羽圃,就會(huì)消耗很多機(jī)器的資源,比如數(shù)據(jù)帶寬占滿浊服、存儲(chǔ)一下子增加了很多统屈。

3)物化視圖實(shí)戰(zhàn)
#建表語句

CREATE TABLE hits_test(

EventDate Date,

CounterID UInt32,

UserID UInt64,

URL String,

Income UInt8

)ENGINE = MergeTree()

PARTITION BY toYYYYMM(EventDate)

ORDER BY (CounterID, EventDate, intHash32(UserID))

SAMPLE BY intHash32(UserID)

SETTINGS index_granularity = 8192

#導(dǎo)入數(shù)據(jù)

INSERT INTO hits_test

SELECT EventDate,CounterID,UserID,URL,Income FROM hits_v1 limit 10000;

#創(chuàng)建物化視圖
CREATE MATERIALIZED VIEW hits_mv

ENGINE=SummingMergeTree

PARTITION BY toYYYYMM(EventDate) ORDER BY (EventDate, intHash32(UserID))

AS SELECT UserID,EventDate,count(URL) as ClickCount,sum(Income) AS IncomeSum FROM hits_test

WHERE EventDate >= '2014-03-20' #設(shè)置更新點(diǎn),該時(shí)間點(diǎn)之前的數(shù)據(jù)可以另外通過insert into select …… 的方式進(jìn)行插入 

GROUP BY UserID,EventDate;

#或者可以用下列語法,表 A 可以是一張 mergetree 表

CREATE MATERIALIZED VIEW 物化視圖名 TO 表 A AS SELECT FROM 表 B;

#不建議添加 populate 關(guān)鍵字進(jìn)行全量更新

#導(dǎo)入增量數(shù)據(jù)

INSERT INTO hits_test

SELECT EventDate,CounterID,UserID,URL,Income FROM hits_v1 WHERE EventDate >= '2014-03-23' limit 10;

#查詢物化視圖

SELECT * FROM hits_mv;

#導(dǎo)入歷史數(shù)據(jù)

INSERT INTO hits_mv

SELECT UserID,EventDate,count(URL) as ClickCount, sum(Income) AS IncomeSum FROM hits_test

WHERE EventDate = '2014-03-19' GROUP BY UserID,EventDate
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末牙躺,一起剝皮案震驚了整個(gè)濱河市愁憔,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌孽拷,老刑警劉巖吨掌,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異脓恕,居然都是意外死亡膜宋,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門炼幔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來秋茫,“玉大人,你說我怎么就攤上這事乃秀「刂” “怎么了?”我有些...
    開封第一講書人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵跺讯,是天一觀的道長(zhǎng)枢贿。 經(jīng)常有香客問我,道長(zhǎng)刀脏,這世上最難降的妖魔是什么局荚? 我笑而不...
    開封第一講書人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上耀态,老公的妹妹穿的比我還像新娘轮傍。我一直安慰自己,他們只是感情好茫陆,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開白布金麸。 她就那樣靜靜地躺著,像睡著了一般簿盅。 火紅的嫁衣襯著肌膚如雪挥下。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,125評(píng)論 1 297
  • 那天桨醋,我揣著相機(jī)與錄音棚瘟,去河邊找鬼。 笑死喜最,一個(gè)胖子當(dāng)著我的面吹牛偎蘸,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播瞬内,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼迷雪,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了虫蝶?” 一聲冷哼從身側(cè)響起章咧,我...
    開封第一講書人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎能真,沒想到半個(gè)月后赁严,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡粉铐,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年疼约,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蝙泼。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡程剥,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出汤踏,到底是詐尸還是另有隱情倡缠,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布茎活,位于F島的核電站,受9級(jí)特大地震影響琢唾,放射性物質(zhì)發(fā)生泄漏载荔。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一采桃、第九天 我趴在偏房一處隱蔽的房頂上張望懒熙。 院中可真熱鬧丘损,春花似錦、人聲如沸工扎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)肢娘。三九已至呈础,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間橱健,已是汗流浹背而钞。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留拘荡,地道東北人臼节。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像珊皿,于是被迫代替她去往敵國(guó)和親网缝。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

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