隨著數(shù)字化技術對各行各業(yè)的不斷滲透,人大金倉在金融、能源、電信等行業(yè)逐步進入深水區(qū),面臨越來越多的核心類系統(tǒng)改造升級,這些系統(tǒng)不僅需要滿足在線交易系統(tǒng)運行的高實時性要求,還需要保證高效分析能力以幫助客戶進行業(yè)務決策。
數(shù)據(jù)庫中SQL表達式及PLSQL代碼實現(xiàn)的都是通用邏輯,這就導致在語句執(zhí)行過程中可能形成大量不必要的邏輯跳轉(zhuǎn)和代碼分支遍歷,進而成倍甚至成指數(shù)級增加底層指令的執(zhí)行,造成CPU過高壓力。尤其在較為復雜分析類計算場景中,這種性能損耗尤其嚴重。
為了解決這種無效性能損耗,KES使用動態(tài)編譯(Just-in-time compilation,JIT)技術,將代碼扁平化執(zhí)行。簡單說就是通過直接調(diào)用對應的函數(shù),并且在已知輸入情況下精簡代碼邏輯分支的方式,在復雜計算的分析場景下顯著降低CPU單位負載壓力,有效提高數(shù)據(jù)庫整體性能。
什么是JIT
在解釋JIT之前,我們先來了解下什么是編譯器:它是將高級語言源代碼翻譯成機器語言(或翻譯成比原始程序低級代碼)的程序。
從“代碼”到“代碼”的轉(zhuǎn)換:

轉(zhuǎn)換后的代碼:
-計算機可以直接執(zhí)行的機器語言(本機代碼);
-比原始程序低級的中間語言代碼。
在以前,程序通常有兩種編譯運行方式 - 靜態(tài)編譯與動態(tài)直譯,現(xiàn)如今又出現(xiàn)了即時編譯方式。
提前 (Ahead-of-Time: AOT) 編譯 - 即靜態(tài)編譯:在運行應用程序之前預編譯應用程序的編譯。
典型代表:C
-將源代碼 (.c) 轉(zhuǎn)換為機器語言(本機代碼);
-建二進制文件;

2、解釋器(interpreter)- 動態(tài)直譯:執(zhí)行以編程語言編寫的源代碼或中間表達式并按順序解釋它們的程序。
典型代表:JAVA-JVM
-代碼“在解釋的同時執(zhí)行”;
-優(yōu)點是無需事先編譯,程序獨立于特定架構;
-缺點是運行性能低。
3、即時 (JIT) 編譯:在軟件執(zhí)行期間編譯代碼以提高執(zhí)行速度的編譯器;
JAVA
-在運行時將頻繁執(zhí)行的方法編譯為機器代碼;

Python + Numba
-在運行時編譯并運行指定函數(shù)。
即時 (JIT) 編譯融合了前二種編譯方式,一句一句編譯源代碼執(zhí)行,同時將編譯過的代碼緩存起來以降低性能損耗。相對于靜態(tài)編譯,即時編譯的代碼可以處理延遲綁定并增強安全性。簡單的說,JIT 是一種提高程序運行效率的方法。
KES如何實現(xiàn)JIT
KES基于LLVM實現(xiàn)JIT特性。

KES把對應的JIT 的提供者封裝成一個依賴庫,從而避免了JIT 對內(nèi)核代碼的侵入性。用戶可以按需開啟或關閉JIT功能;通過進一步的抽象,KES還提供支持后期擴展不同JIT的解決方案。其JIT實現(xiàn)過程概述如下:
1.表達式的中間表示(Exprstate)轉(zhuǎn)換為LVMM的中間表示(LVMM IR);
2.使用LVMM進行JIT編譯,轉(zhuǎn)換為機器代碼;
3.KES執(zhí)行器將其做為內(nèi)部函數(shù)調(diào)用執(zhí)行;

KES基于JIT提供的優(yōu)化項
1、表達式計算優(yōu)化
針對WHERE 條件判斷、聚合運算等場景實時將表達式的路徑編譯為具體代碼執(zhí)行,在此過程中大量的不必要的調(diào)用和分支跳轉(zhuǎn)會被優(yōu)化掉。
2、存取層優(yōu)化
數(shù)據(jù)庫執(zhí)行器通過存取層裝載數(shù)據(jù),針對特定的表結構,可以定制讀取和解析元組的代碼。如在解析元組的流程中,根據(jù)表結構動態(tài)生成的代碼,無需做數(shù)據(jù)類型的重復判斷,只按照順序解析數(shù)據(jù);以及在獲取部分列時實現(xiàn)直接根據(jù)對應偏移量提取的數(shù)據(jù),跳過不需要提取的列,從而降低計算及I/O開銷。隨著處理的數(shù)據(jù)量的增加,節(jié)省的計算及I/O量將是驚人的。
3、執(zhí)行器流程優(yōu)化
LLVM中實現(xiàn)了對產(chǎn)生的中間表示代碼(IR)的優(yōu)化,這一定程度上也會提升數(shù)據(jù)庫查詢的執(zhí)行速度。從每一行數(shù)據(jù)的處理優(yōu)化提升到整條 SQL 的處理流程優(yōu)化:從傳統(tǒng)的相對低效的流水線執(zhí)行方式調(diào)整為循環(huán)批量處理方式,從而充分利用 CPU緩存,盡量避免去相對慢得多的內(nèi)存中存取數(shù)據(jù);再結合 CPU 向量計算相關指令集,進一步提高性能。
JIT會提升CPU密集型查詢的性能,而對于短查詢的優(yōu)化有限,KES默認開啟動態(tài)編譯(JIT),運行時會比較查詢的評估代價與JIT代價閥值的大小,判斷是否執(zhí)行JIT編譯。用戶也可以根據(jù)業(yè)務需要主動設置JIT參數(shù)關閉動態(tài)編譯。
JIT優(yōu)化性能實測
下面通過一個客戶業(yè)務分析場景的脫敏簡化版對比說明JIT對SQL執(zhí)行性能的提升:


EXPLAN ANALYZE結果:

總結展望
JIT可以幫助KES數(shù)據(jù)庫優(yōu)化SQL執(zhí)行邏輯,加快復雜SQL的查詢速度,從而提升KES整體性能。在TPC-H等數(shù)據(jù)庫測試中,KES的JIT編譯表達式執(zhí)行速度快了不止20%;在JIT模式下,創(chuàng)建索引的速度普遍可以提高5%-19%。
作為國內(nèi)成立最早、底蘊最深的數(shù)據(jù)庫國家隊,人大金倉始終以用戶為中心,致力于提供卓越的數(shù)據(jù)庫產(chǎn)品與服務。金倉人在廣泛關注及學習前沿技術的同時,堅持自主創(chuàng)新,不斷落地新理論,融合新技術,以滿足日趨多元且極致的新需求,提升產(chǎn)品核心競爭力,持續(xù)為千行百業(yè)數(shù)字化轉(zhuǎn)型升級賦能。






