openGauss學(xué)習(xí)筆記-52 openGauss 高級(jí)特性-LLVM52.1 適用場(chǎng)景52.2 非適用場(chǎng)景52.3 其他因素對(duì)LLVM性能的影響52.4 LLVM使用建議
openGauss學(xué)習(xí)筆記-52 openGauss 高級(jí)特性-LLVM
openGauss借助LLVM(Low Level Virtual Machine)提供的庫函數(shù),依據(jù)查詢執(zhí)行計(jì)劃樹,將原本在執(zhí)行器階段才會(huì)確定查詢實(shí)際執(zhí)行路徑的過程提前到執(zhí)行初始化階段,從而規(guī)避原本查詢執(zhí)行時(shí)候伴隨的函數(shù)調(diào)用、邏輯條件分支判斷以及大量的數(shù)據(jù)讀取等問題,以達(dá)到提升查詢性能的目的。
LLVM動(dòng)態(tài)編譯技術(shù)可以為每個(gè)查詢生成定制化的機(jī)器碼用于替換原本的通用函數(shù)。通過減少實(shí)際查詢時(shí)冗余的條件邏輯判斷、虛函數(shù)調(diào)用并提高數(shù)據(jù)局域性,從而達(dá)到提升查詢整體性能的目的。
由于LLVM需要消耗額外的時(shí)間預(yù)生成IR中間態(tài)表示并編譯成機(jī)器碼,因此在小數(shù)據(jù)量場(chǎng)景或查詢本身耗時(shí)較少時(shí),可能引起性能的劣化。
52.1 適用場(chǎng)景
-
支持LLVM的表達(dá)式
查詢語句中存在以下的表達(dá)式支持LLVM優(yōu)化:
Case…when… 表達(dá)式
In表達(dá)式
-
Bool表達(dá)式
And
Or
Not
-
BooleanTest表達(dá)式
IS_NOT_UNKNOWN:對(duì)應(yīng)SQL語句IS NOT UNKNOWN
IS_UNKNOWN:對(duì)應(yīng)SQL語句IS UNKNOWN
IS_TRUE:對(duì)應(yīng)SQL語句IS TRUE
IS_NOT_TRUE:對(duì)應(yīng)SQL語句IS NOT TRUE
IS_FALSE:對(duì)應(yīng)SQL語句IS FALSE
IS_NOT_FALSE:對(duì)應(yīng)SQL語句IS NOT FALSE
-
NullTest表達(dá)式
IS_NOT_NULL
IS_NULL
Operator表達(dá)式
-
Function表達(dá)式
lpad
substring
btrim
rtrim
length
Nullif表達(dá)式
表達(dá)式計(jì)算支持的數(shù)據(jù)類型包括bool, tinyint, smallint, int, bigint, float4, float8, numeric, date, time, timetz, timestamp, timestamptz, interval, bpchar, varchar, text, oid。
僅當(dāng)表達(dá)式出現(xiàn)在向量化執(zhí)行引擎中Scan節(jié)點(diǎn)的filter、Hash Join節(jié)點(diǎn)中的complicate hash condition、hash join filter、hash join target, Nested Loop節(jié)點(diǎn)中的filter、join filter, Merge Join節(jié)點(diǎn)的merge join filter, merge join target, Group節(jié)點(diǎn)中的filter表達(dá)式時(shí),才會(huì)考慮是否使用LLVM動(dòng)態(tài)編譯優(yōu)化。
-
支持LLVM的算子:
Join :HashJoin
Agg :HashAgg
Sort
其中HashJoin算子僅支持Hash Inner Join,對(duì)應(yīng)的hash cond僅支持int4、bigint、bpchar類型的比較;HashAgg算子僅支持針對(duì)bigint、numeric類型的sum及avg操作,且group by語句僅支持int4、bigint、bpchar,text,varchar,timestamp類型操作,同時(shí)支持count(*)聚集操作。Sort算子僅支持對(duì)int4,bigint,numeric,bpchar,text,varchar數(shù)據(jù)類型的比較操作。除此之外,無法使用LLVM動(dòng)態(tài)編譯優(yōu)化,具體可通過explain performance工具進(jìn)行顯示。
52.2 非適用場(chǎng)景
不支持小數(shù)據(jù)量表使用LLVM動(dòng)態(tài)編譯優(yōu)化。
不支持生成非向量化執(zhí)行路徑的查詢作業(yè)。
52.3 其他因素對(duì)LLVM性能的影響
LLVM優(yōu)化效果不僅依賴于數(shù)據(jù)庫內(nèi)部具體的實(shí)現(xiàn),還與當(dāng)前所選擇的硬件環(huán)境等有關(guān)。
-
表達(dá)式調(diào)用C-函數(shù)個(gè)數(shù)
數(shù)據(jù)庫內(nèi)部針對(duì)表達(dá)式計(jì)算并未實(shí)現(xiàn)全codegen,即在整個(gè)表達(dá)式計(jì)算中部分表達(dá)式實(shí)現(xiàn)了codegen,部分直接調(diào)用原本的C代碼。如果整個(gè)表達(dá)式計(jì)算中后者占據(jù)了主要部分,使用LLVM動(dòng)態(tài)編譯優(yōu)化,可能會(huì)導(dǎo)致性能劣化。通過設(shè)置log_min_message的級(jí)別為DEBUG1可以查看到哪些表達(dá)式直接調(diào)用了C代碼實(shí)現(xiàn)。
-
內(nèi)存資源
LLVM特性的一個(gè)重要思想是保障數(shù)據(jù)的局域特性,即數(shù)據(jù)應(yīng)盡可能的存放在寄存器中。同時(shí)應(yīng)減少數(shù)據(jù)加載,因此在使用LLVM優(yōu)化時(shí)應(yīng)設(shè)置足夠大的work_mem,保證對(duì)應(yīng)使用LLVM優(yōu)化的執(zhí)行代碼整個(gè)過程在內(nèi)存中實(shí)現(xiàn),否則可能引起性能劣化。
-
優(yōu)化器代價(jià)估算
LLVM特性實(shí)現(xiàn)了簡(jiǎn)易的代價(jià)估算模型,即依據(jù)當(dāng)前參與節(jié)點(diǎn)運(yùn)算的表大小決定當(dāng)前節(jié)點(diǎn)是否考慮使用LLVM動(dòng)態(tài)編譯優(yōu)化。如果優(yōu)化器低估了實(shí)際參與運(yùn)算的行數(shù),則原本可獲得收益的未正常獲得收益。反之亦然。
52.4 LLVM使用建議
目前LLVM在數(shù)據(jù)庫內(nèi)核側(cè)已默認(rèn)打開,用戶可結(jié)合上述的分析進(jìn)行配置,總體建議如下:
設(shè)置合理的work_mem,在允許的條件下盡可能設(shè)置較大的work_mem,如果出現(xiàn)大量下盤,則建議關(guān)閉LLVM動(dòng)態(tài)編譯優(yōu)化(通過設(shè)置enable_codegen=off實(shí)現(xiàn))。
設(shè)置合理的codegen_cost_threshold(默認(rèn)值為10000),確保小數(shù)據(jù)量場(chǎng)景下避免使用LLVM動(dòng)態(tài)編譯優(yōu)化。當(dāng)codegen_cost_threshold的值設(shè)定后,因使用LLVM動(dòng)態(tài)編譯優(yōu)化引入性能劣化,則建議增加codegen_cost_threshold的取值。
-
對(duì)于表達(dá)式計(jì)算使用LLVM動(dòng)態(tài)編譯優(yōu)化,如果存在大量的調(diào)用C-函數(shù)的場(chǎng)景,建議關(guān)閉LLVM動(dòng)態(tài)編譯優(yōu)化。
[圖片上傳失敗...(image-4b6c0b-1693122389841)]
說明: 在資源許可的情況下,數(shù)據(jù)量越大,可獲得的性能提升效果越好。
?? 點(diǎn)贊,你的認(rèn)可是我創(chuàng)作的動(dòng)力!
?? 收藏,你的青睞是我努力的方向!
?? 評(píng)論,你的意見是我進(jìn)步的財(cái)富!
