對國產(chǎn)數(shù)據(jù)庫廠商提幾個關(guān)于SQL引擎的小需求
國產(chǎn)數(shù)據(jù)庫迎來了一個高速發(fā)展的好時期,大量的企業(yè)用戶正在將他們的數(shù)據(jù)庫系統(tǒng)遷移到開源和國產(chǎn)數(shù)據(jù)庫平臺上。不過我們的國產(chǎn)數(shù)據(jù)庫廠商在大量收割用戶和“數(shù)鈔票”的時候,廣大的用戶也在期盼著國產(chǎn)數(shù)據(jù)庫變得更好用。SQL引擎是數(shù)據(jù)庫最為核心的組件之一,因此大量國產(chǎn)數(shù)據(jù)庫廠商在內(nèi)卷競爭的時候,也需要能夠做出一些讓廣大用戶滿意的功能來。

我們團隊常年從事系統(tǒng)優(yōu)化和數(shù)據(jù)庫運維工具開發(fā),這些年也接觸了大量的用戶,遇到過大量的數(shù)據(jù)庫的坑,其中大部分是和SQL引擎有關(guān)的。因此今天我也代表廣大的用戶,給國產(chǎn)數(shù)據(jù)庫提出一些關(guān)于SQL引擎方面的功能需求。希望在新一個版本的國產(chǎn)數(shù)據(jù)庫中,能夠看到這些功能被逐步實現(xiàn)了。
如果最希望國產(chǎn)數(shù)據(jù)庫SQL引擎具有的功能就是全功能的HASH JOIN,大家都知道HASH JOIN是解決大數(shù)據(jù)量的表關(guān)聯(lián)問題的最有效的連接方式。Oracle的HASH JOIN很強大,大量復(fù)雜的連接條件,都可以通過HASH JOIN來擺平。雖然現(xiàn)在很多開源、國產(chǎn)數(shù)據(jù)庫都支持HASH JOIN,不過對HASH JOIN的支持上依然存在很多的盲點。如果遇到某些情況下,正好HASH JOIN無法使用,那么這條SQL就只剩下改寫一條路了,這對于開發(fā)人員和DBA來說就是災(zāi)難。
第二個需求是SQL指紋和執(zhí)行計劃指紋。SQL指紋和SQL ID不完全是一回事,SQL ID只能指向一條唯一的SQL語句,而SQL指紋可以將一組存在略微差異的SQL語句歸類為一種SQL。比如我們有一條SQL,除了某些大小寫不同,其他是相同的,或者只有某個變量不同,其他是相同的,那么這些不同的SQL應(yīng)該是同一條SQL,雖然這些SQL的SQL ID可能不同,不過這些SQL具有相同的指紋信息。通過這些指紋可以找到這類相同的SQL,進行統(tǒng)一的分析。執(zhí)行計劃指紋是指完全相同的執(zhí)行計劃,有可能不同SQL ID的SQL會使用相同的執(zhí)行計劃,在SQL中會有一個執(zhí)行計劃指紋的標識,指向這個執(zhí)行計劃。通過“執(zhí)行計劃指紋”,我們可以減少保存在內(nèi)存中的執(zhí)行計劃數(shù)量,不管是否實現(xiàn)了全局執(zhí)行計劃,都可以將執(zhí)行計劃存儲在一個共享內(nèi)存區(qū)域中,供監(jiān)控分析人員使用。類似的SQL指紋與執(zhí)行計劃指紋的功能實際上在Oracle數(shù)據(jù)庫中大多數(shù)已經(jīng)實現(xiàn)了,有興趣的朋友可以去研究一下。
第三個需求是HINT,優(yōu)化器的提升是相當困難的,需要大量的資金投入和時間的沉淀才可以做得越來越好,絕對無法依靠某幾個聰明的高手就可以完成。如果遇到了CBO優(yōu)化器真的無法做出正確判斷,非要使用錯誤的執(zhí)行計劃的時候,開發(fā)人員還是可以通過HINT來強制矯正執(zhí)行計劃的。目前也有一些國產(chǎn)數(shù)據(jù)庫和開源數(shù)據(jù)庫支持hint了。不過在實現(xiàn)方法上,很多國產(chǎn)和開源數(shù)據(jù)庫是通過外掛方式,利用數(shù)據(jù)庫代碼中的鉤子來實現(xiàn)的,另外HINT支持的操作也還不是很完整。通過鉤子的插件實現(xiàn)方式還是沒有原生態(tài)的內(nèi)核支持效率更高,在內(nèi)核中直接支持豐富的HINT絕對是提升國產(chǎn)數(shù)據(jù)庫SQL解析效率的必然途徑。在HINT支持的操作方面,HINT不僅僅可以強制指定某種執(zhí)行方案,還可以實現(xiàn)集群計算環(huán)境中的強讀寫分離、弱讀寫分離等功能。比如設(shè)定集群計算環(huán)境中MASTER選擇的策略,以及指明某操作可以放置于只讀節(jié)點,甚至指明某個操作是弱一致性操作,運行數(shù)據(jù)延時的最大限制等。這些HINT往往需要集群計算環(huán)境被納入到數(shù)據(jù)庫的內(nèi)核中,而不僅僅是外掛的。
第四個需求是OUTLINES的原生態(tài)支持,當我們無法直接修改SQL,添加HINT來強制指定一個比較優(yōu)化的執(zhí)行計劃的時候,就只能依靠OUTLINES了。傳統(tǒng)的OUTLINES只能針對某個SQL ID,如果存在一些沒有使用綁定變量的情況,就沒辦法通過SQL ID來指定OUTLINES。而往往一個系統(tǒng)中,這些SQL才是最常用的,也是最重要的。在OUTLINES的實現(xiàn)上,如果可以通過SQL指紋來設(shè)定,那么OUTLINES將會有更廣泛的用途。
第五個需求是長時間運行的SQL執(zhí)行進度可視化,提供一個類似于Oracle V$SESSION_LONGOPS的外部接口視圖。不過希望能夠比Oracle提供更多一些的信息。比如當前這個操作來自于哪個執(zhí)行計劃(執(zhí)行計劃指紋),以及這個操作處于執(zhí)行計劃的第幾個步驟。當然這種SQL執(zhí)行進度可視化僅僅顯示長時間執(zhí)行的操作,只有當執(zhí)行計劃中的某個算子執(zhí)行成本超過一定閾值的時候,才需要輸出到接口中,否則這種輸出會影響SQL引擎的效率。這部分功能實現(xiàn)只要到某個算子級別就可以了,不需要做SQL級別的,SQL引擎還是性能為先,可視化是次要的。
其實SQL引擎中的優(yōu)化器是改進難度最大的部件,需要有大量的應(yīng)用案例來促進其優(yōu)化和改進。而且有些優(yōu)化器的功能優(yōu)化難度極大,要做出一個優(yōu)秀的CBO優(yōu)化器其實不是一朝一夕就能夠完成的。不過在優(yōu)化器達到完美之前,必須是夠用的。也就是能夠盡可能讓我們的開發(fā)人員不要總是面臨SQL不改寫就無法正常運行的困境。用戶的應(yīng)用場景十分復(fù)雜,因此作為國產(chǎn)數(shù)據(jù)庫的開發(fā)者,集中力量去解決必須解決的問題,剩下的問題通過HINT,OUTLINES這樣似乎不是太智能化的手段來彌補優(yōu)化器的能力不足,也是必須的。不管怎么說,能夠解決用戶問題的數(shù)據(jù)庫就是好數(shù)據(jù)庫。
























