留給CBO優化器的彎道不多了
?前幾天一個做數據庫產品的朋友和我聊起在國產數據庫上的彎道超車問題,他覺得對于通用關系型數據庫,Oracle已經領先太多了,如果不彎道超車,國產數據庫永遠沒有機會趕上Oracle。彎道超車一直被很多朋友看作是超越的捷徑,不過我認為彎道超車一定是以實力作為后盾才能夠完成的。要想彎道超車,后車的引擎必須高于前車,至少是二者相當,沒有實力做保障,彎道技術再好,也是很難完成超車的。
在通用關系型數據庫領域,想要對Oracle實現彎道超車,大家都會選擇CBO優化器。AI4DB是被大家寄予厚望的。通過AI算法的輔助來糾正執行計劃中的錯誤,或者幫助某條SQL選擇一個更好的執行計劃。其主要方法是基于歷史數據的分析,通過一定的參數(比如表分析數據、歷史執行計劃的效率等),通過算法計算執行計劃的成本,在重大決策中輔助CBO的規則引擎,比如當HASH JOIN和NESTED LOOP經常會選錯的時候,通過AI算法輔助,讓CBO選擇的執行計劃更為準確。
實際上Oracle這些年也一直CBO上發力,動態CURSOR是Oracle用于解決這個問題的方法,當SQL在執行過程中發現NESTED LOOP成本過高的時候,自動將目前的執行暫停,更換為HASH JOIN,從而避免某些SQL出現嚴重的性能問題。只不過Oracle目前的算法還不夠完善,因此動態CURSOR有時候還會出錯。
Oracle的CBO優化器是基于數據模型的優選算法的,其主要方法是通過各種統計數據,對某個SQL的不同算子計算成本,最后將一條SQL的各種執行方式的成本都算完后,選擇其中成本最低的執行計劃去執行。這種方法也是目前絕大多數數據庫系統分析執行計劃的基礎算法。到目前的版本為止,Oracle并沒有選擇通過AI算法來獲得執行計劃,而是繼續沿用其傳統的算法。不過隨著Oracle的數十年的發展,其CBO優化器的核心算法基礎上,已經積累了大量的補丁,這些補丁都是對核心主算法的糾正,在Oracle內部被稱為FIX。每個FIX實際上就是一個特殊場景下SQL選擇執行計劃中的修正模型,都是在實戰中遇到問題后,標準CBO算法無法解決問題時的一種特殊處理,也可以稱為經驗模型。此外,Oracle還將其中的一些特別重要的修正進行了特殊的處理,設置了一些隱含參數加以控制。這些修正往往不是CBO優化器的不足,而是在不同的應用場景中,特殊的用戶數據與用戶硬件環境可能導致CBO優化器產生錯誤的選擇,通過這些參數可以加以調整。其中最為著名的莫過于optimizer_index_cost_adj,這個參數可以調整CBO優化器在計算索引掃描時的成本,在二十年前的Oracle 8i/9i時代,我們經常通過調整這個參數來避免不必要的對全表掃描的錯誤選擇,讓數據庫更傾向于使用索引掃描。
在Oracle 11.2.0.4中,CBO優化器的可調整參數有329個,FIX有846個。到了19.15.0.0版本,CBO優化器可調整參數的數量高達612個,FIX的數量達到了1369個。實際上每個FIX后面都有無數個用戶的痛苦經歷,是Oracle數據庫的CBO優化器在用戶環境中遇到了問題后的修正。
Oracle數據庫的優化器是十分優秀的,這一點大家都是公認的,但是其優秀的優化器依然無法解決所有的用戶的問題,依然需要不斷的通過添加參數來做更精細的控制,甚至加入某些特殊的修正來解決問題。
目前我們國產數據庫的優化器恐怕還在重點完善CBO優化器的核心算法,還沒有遇到過如此多的實戰案例,發現那么多主邏輯可能存在的問題。這些參數與FIX必須是在大量的實戰中獲得的,因此有些國產數據庫廠家想另辟蹊徑了。通過AI4DB是不是可以繞開這個問題,實現在CBO上的彎道超車呢?恐怕有此想法的朋友要失望了,CBO優化器是基于統計數據與算法規則的,歷史的SQL執行情況可以提供參考,但是無法作為下一次解析SQL時的可靠依據。因為數據在不斷的變化,參數也在變化,而CBO優化器的每次解析,都決定了SQL語句是否能夠合理的執行。一次錯誤的解析很可能引發一場災難。因此AI算法在這個場景中可以起到輔助發現SQL問題的作用,但是無法替代規則來生成執行計劃。我們的CBO優化器也只能在實戰中不斷的經受挑戰,不斷的經歷痛苦的折騰,才能變得越來越強大。當我們的優化器的FIX和可調整參數能夠達到Oracle的時候,才真正算是成熟了。CBO優化器成長的最佳途徑是在實戰中不斷完善,而不是憑著我們的研發人員的想象力,在家里閉門造車。
先不要空談彎道超車,扎扎實實的在用戶廠家中去修煉,把優化器一點點做好吧,實際上在現階段,能夠先遠遠的跟上最先進的數據庫產品,已經是國產數據庫的成功了。