昨天關于NESTED LOOP BATCHING的文章,有朋友說這是執行計劃選擇錯誤,而不是笛卡爾積的問題。實際上此類SQL性能問題,都是因為統計數據而選錯了執行計劃。
昨天談到的問題是因為NESTED LOOP BATCHING的存在,讓NLJ的執行計劃選擇變得更為復雜了,NESTED LOOP BATCHING有三個行源,兩層NESTED LOOP,Oracle實際上是把一個兩表連接改為三個行源(其中一張表產生兩個行源)的連接,并且NESTED LOOP BATCHING可以使用笛卡爾積來處理內循環,這種連接實際上是更為復雜了。因此在統計信息不準,并且表上存在相類似索引或者有共同索引字段索引的時候,很容易選錯索引。
Oracle數據庫為什么要如此拼命的去提升優化器,提升對數據的處理能力呢?這種情況,讓開發商分拆了SQL,取消了表連接,不就不會出問題了呢?實際上這和我今天要談的問題是有關聯的。
前幾天有人問我,如果說操作系統是信息化的奠基石,那么數據庫算什么?我想了想說,從這個角度講,數據庫是信息化的加速器。
現代的大型數據庫系統已經和40多年前剛剛出現的數據庫系統完全不是一個概念了,當初的RDBMS主要是作為數據存儲和檢索的基礎設施,能實現高效的存取數據就可以了,而數據處理還是由應用程序去完成。
而現在的大型關系型數據庫系統不僅僅是一個數據存儲的平臺,更是一個數據計算的平臺。如果在現代社會里,要求RDBMS回歸數據存儲與檢索的功能,而讓更多的數據處理和復雜計算交給程序代碼去做,在大多數應用場景下,這實際上是一種技術的倒退,而不是真正的進步。
90年代初,我剛剛參加工作的時候,作為一個軟件工程師,接觸的數據庫系統是十分簡單的,當時還不是RDBMS,而是一個記錄管理系統(RMS),我們頂多可以通過索引加速某些檢索,不過數據的復雜處理都需要我在C語言的程序里通過自己寫算法來進行。這種開發是十分低效,幾個月后,我第一次使用大型數據庫系統DEC-RDB的時候,發現以前我花半天時間寫的處理的數據的程序,改用SQL語句寫,幾分鐘就搞定了,大部分的時候處理效率還比我寫的程序高。從那開始我就喜歡上了關系型數據庫,這是一個提高開發效率的利器。
從90年代C/S架構逐漸流行開始,位于應用系統后端的大型集中式關系型數據庫就已經不是那個當年只是用來存儲一些數據的小容器了,而變成了一個數據計算的平臺。從那時候起,再把數據庫定位為數據存取的IT基礎設施就不合適了。以Oracle數據庫為例,它不斷地把各種數據計算的功能整合在RDBMS中,空間計算、XMLDB等功能不斷地充實著Oracle的武器庫,甚至在最新的Oracle數據庫里,區塊鏈表、深度學習模型等都已經成為了標配的功能。開發人員不需要有太深的人工智能算法和區塊鏈的理論,就可以快速高效的開發相關的應用系統了。
后端強大的計算能力,也讓前端開發人員得到了極大的解放,只要能畫個界面,寫點簡單的過程化語言代碼的人都可以成為一個合格的程序員了。這個趨勢到了B/S架構時代就更為明顯了。J2EE框架讓應用程序開發的門檻進一步降低,很多中文系的畢業生都加入到了碼農的隊伍里了。
如果大型關系型數據庫沒有發展成為一個數據存儲、數據處理、數據計算的綜合性平臺,那么僅僅依靠那些數量有限的長得像黑客一樣的人,寫著C語言的代碼去開發管理信息系統,那么我想我們的信息化進程至少要滯后十年二十年。正是大型關系型數據庫讓應用開發的門檻降低到了一個十分低的低點,才大大促進了信息化的發展。從這一點上來說,數據庫是信息化的加速器,并不夸張。
最近似乎有一種思潮,那就是數據庫的功能太強大了,做了太多程序員該做的事情,因此應用的本質需要有所回歸,讓一些數據處理的工作從數據庫中剝離出來,回歸到程序中來。這實際上是互聯網公司這些年都在做的事情,因為集中式數據庫是一個中心單點,是極不容易橫向擴展的,對互聯網業務的發展是一個極大的制約。因此互聯網企業采用分布式架構來打破集中式數據庫的瓶頸,將數據分散到海量的分布式的小型數據庫中。這種數據架構的變革讓以前大型數據庫的很多集中式計算的功能都無法完成了,數據庫逐漸又退化為數據存取的基礎設施了。
互聯網企業的成功讓很多人都在反思大型數據庫是不是撈過界了,是不是真的需要讓數據庫的功能向其遠祖退化。有一陣子我也是這種思潮的粉絲,認為互聯網企業的成功可以復制到傳統行業中去,從而徹底解決集中式數據庫的問題。不過隨著這些年在傳統行業里摸爬滾打,我發現互聯網企業的成功經驗并不一定都能夠向傳統行業去復制,因為業務爆發式的發展,需要處理的數據越來越多,企業管理越來越依賴信息化手段,這導致了信息系統研發的壓力越來越大。而我們的研發能力的建設往往要慢得多,因此往往傳統行業學習互聯網企業的努力變成了東施效顰。
如果所有的傳統行業應用開發能力要達到互聯網企業的水平,那么具有很高數據復雜處理能力的的程序員就不夠用了。信息化的發展是不等人的,不會等我們再花數年的時間去培養一批能夠利用互聯網架構開發系統的高水平的碼農,大量的信息系統的建設還只能采用改良的傳統架構。程序員還是需要以寫SQL為主去實現復雜的業務邏輯。因此,在目前這個時代里,我們還需要十分強大的數據庫來支撐信息化建設,數據庫向著更加復雜的數據處理綜合平臺發展的趨勢也會越來越快,哪個數據庫產品能夠更加高效,更加低代碼的實現復雜數據處理,哪個數據庫在未來就能占據更大的市場份額。
高效的處理復雜數據對數據庫廠商提出了更高的要求,我們的國產數據庫不僅僅是要模仿國外商用數據庫的形,更要追趕別人在數據處理種類,能力,性能等方面的技術,盡快把自己的產品與競品的技術差距縮小了。
最后要說的一點,數據庫提升數據處理的能力抑或是研發人員方便的使用數據庫的超強的數據計算能力并不是說開發人員可以肆無忌憚的寫SQL語句,從而讓數據庫承受巨大的壓力。數據庫可以高效的處理復雜的數據和業務邏輯,并不等于一切都交給數據庫去做。當數據庫對某些處理能力不足的時候,還是需要我們的開發人員去優化去規避的。這里只想表達的意思是,限制一條SQL不能超過3張表關聯,不能寫太復雜的SQL,這只應該是某些技術還不夠成熟的特殊階段的一些限制,隨著數據庫技術的發展,這些限制肯定是越少越好。
原文鏈接:https://mp.weixin.qq.com/s/3UEv_M62DXk77OCD_ULhPA