openGauss內(nèi)核分析(七):SQL by pass & 經(jīng)典執(zhí)行器
執(zhí)行引擎一般負責查詢的執(zhí)行,執(zhí)行引擎在SQL執(zhí)行棧中起到接收優(yōu)化器生成的執(zhí)行計劃Plan、并對通過存儲引擎提供的數(shù)據(jù)讀寫接口,實現(xiàn)對數(shù)據(jù)進行計算得到查詢的結(jié)果集。

在典型的OLTP場景中,簡單查詢占了很大一部分比例。這種查詢的特征是只涉及單表和簡單表達式的查詢,因此為了加速這類查詢,openGauss提出了SQL by pass框架,在parse層對這類查詢做簡單的模式判別后,進入到特殊的執(zhí)行路徑里,跳過經(jīng)典的執(zhí)行器執(zhí)行框架,包括算子的初始化與執(zhí)行、表達式與投影等經(jīng)典框架,直接重寫一套簡潔的執(zhí)行路徑,并且直接調(diào)用存儲接口,這樣可以大大加速簡單查詢的執(zhí)行速度。
SQL by pass
enable_opfusion用于控制是否對簡單增刪改查進行優(yōu)化,簡單insert語句在開啟enable_opfusion時的執(zhí)行計劃如下

由于開啟SQL BY PASS,從exec_simple_query過來的語句,會判斷可以走SQL BY PASS,否則進入CreatePortal走經(jīng)典執(zhí)行流程。
進入InsertFusion::execute完成數(shù)據(jù)插入操作。
SQL by pass適應(yīng)的場景有:
只支持indexscan和indexonlyscan,且全部WHERE語句的過濾條件都在索引上。
只支持單表增刪改查,不支持join、using。
只支持行存表,不支持分區(qū)表,表不支持有觸發(fā)器。
不支持active sql、QPS等信息統(tǒng)計特性。
不支持正在擴容和縮容的表。
不支持查詢或者修改系統(tǒng)列。
只支持簡單SELECT語句,例如
僅可以查詢目標表的列,c1和c2列為索引列,后邊可以是常量或者參數(shù),可以使用 for update。
??只支持簡單INSERT語句,例如:
僅支持一個VALUES,VALUES里面的類型可以是常量和參數(shù),不支持returning。
??只支持簡單DELETE語句,例如:
c1和c2列為索引列,后邊可以是常量或者參數(shù)。
??只支持簡單UPDATE語句,例如
c3列修改的值可以是常量和參數(shù),也可以是一個簡單的表達式,c1和c2列為索引列,后邊可以是常量或者參數(shù)。
經(jīng)典的執(zhí)行器
關(guān)閉enable_opfusion,簡單insert的執(zhí)行計劃是這樣的

在這種執(zhí)行流程中Portal是執(zhí)行SQL語句的載體,每一條SQL對應(yīng)唯一的Portal,不同的查詢類型對應(yīng)的Portal類型也有區(qū)別。
Portal的生命周期管理在exec_simple_query函數(shù)中實現(xiàn),該函數(shù)負責Portal創(chuàng)建、執(zhí)行和清理。Portal執(zhí)行的主要執(zhí)行流程包括PortalStart函數(shù)、PortalRun函數(shù)、PortalDrop函數(shù)幾個部分。其中PortalStart函數(shù)負責進行Portal結(jié)構(gòu)體初始化工作,包括執(zhí)行算子初始化、內(nèi)存上下文分配等;PortalRun函數(shù)負責真正的執(zhí)行和運算,它是執(zhí)行器的核心;PortalDrop函數(shù)負責最后的清理工作,主要是數(shù)據(jù)結(jié)構(gòu)、緩存的清理。
?

PortalRun函數(shù)根據(jù)查詢類型進入不同的處理函數(shù)
最終執(zhí)行ExecInsertT完成數(shù)據(jù)插入。
以上分析了簡單insert語句的兩種執(zhí)行流程,對于delete,update,select基本工作流程一致。