硬幣都有兩個(gè)面,而解決問題的時(shí)候總是有條件限制的
DBA群體往往都很固執(zhí),甚至有些人會有執(zhí)念。執(zhí)念有時(shí)候是好東西,比如在探究問題的根本的時(shí)候,不過有時(shí)候會產(chǎn)生一些副作用。最典型的就是對某件事或者問題產(chǎn)生偏見,從而無法正確的思考問題,在探討一個(gè)數(shù)據(jù)庫問題的原因和解決方案的時(shí)候尤其如此。我們總是覺得自己找出的線索鏈條是正確的,自己提出的方案才是最好的解決方案。事實(shí)上,有些事情可能像一枚硬幣一樣,有兩個(gè)面,甚至有多個(gè)面,而我們熟知或者掌握的都只是其中的一部分,都是片面的,局部的。因此在判斷一件事情的時(shí)候,你可以堅(jiān)持你的觀點(diǎn),但是不要急于否定別人的觀點(diǎn),因?yàn)橛锌赡芏叨际怯械览淼摹?/p>
在某些觀點(diǎn)方面,你可以有立場,可以站邊,但是你不要輕易的去否定別人的觀點(diǎn)。就像PG和MySQL數(shù)據(jù)庫哪個(gè)更好的問題上,我總是和客戶說選擇哪種數(shù)據(jù)庫,是要根據(jù)你自己的自身情況和應(yīng)用場景的,但是如果你讓我推薦的話,我更傾向于推薦PG,因?yàn)槲覍G更熟悉一些,如果你用了PG,今后我可以更好的為你服務(wù)。這僅僅是從我個(gè)人的立場出發(fā),并不是說我就認(rèn)為PG遠(yuǎn)遠(yuǎn)好于MySQL。
在定位某個(gè)問題的原因的時(shí)候,我們往往無法定位到根因,無法從根本上解決問題。因此能夠解決某個(gè)問題的方案可能有很多種,這些方案之間有可能不是嚴(yán)格意義上存在哪個(gè)更好的問題。在這種情況下,我們也會更加傾向于采用自己熟悉的或者自己認(rèn)為比較合適的方案。DBA往往希望開發(fā)商通過修改SQL來解決問題,而開發(fā)人員認(rèn)為數(shù)據(jù)庫就應(yīng)該能夠讓他們可以任意寫SQL來實(shí)現(xiàn)業(yè)務(wù)邏輯。在大多數(shù)DBA看來,就是開發(fā)人員瞎寫垃圾SQL導(dǎo)致了系統(tǒng)總出問題,而從研發(fā)人員的立場上看,這個(gè)問題的癥結(jié)是數(shù)據(jù)庫太垃圾了。
在了解了問題的多面性和解決路徑的多樣性之后,我們還要注意的一個(gè)問題是我們解決問題的環(huán)境中,總是有一些條件限制的。十多年前,我在《DBA優(yōu)化日記》里介紹了一個(gè)優(yōu)化項(xiàng)目的全過程。有朋友和我探討這個(gè)案例,認(rèn)為這是我編出來的一個(gè)故事,里面設(shè)定了很多預(yù)設(shè)條件,比如服務(wù)器不能擴(kuò)容,SQL無法大規(guī)模修改等。實(shí)際上這是一個(gè)真的不能再真的案例了,當(dāng)這本書出版后。書中的一些當(dāng)事人紛紛和我聯(lián)系,感謝我把這個(gè)故事講了出來。因?yàn)樵趯?shí)際的工作中,我們總是會遇到各種各樣的限制條件,因此我們在考慮問題的解決方案的時(shí)候,還需要根據(jù)限制條件去裁剪解決路徑。
一個(gè)最典型的問題是,既然絕大多數(shù)數(shù)據(jù)庫的問題都與SQL與SQL的負(fù)載有關(guān),為什么不從SQL與應(yīng)用入手,徹底解決數(shù)據(jù)庫的問題呢?確實(shí)在30多年前,我們解決問題的方案就是這樣的,通過研發(fā)人員對應(yīng)用的優(yōu)化,可以讓資源有限的小型機(jī)與數(shù)據(jù)庫跑得很棒?,F(xiàn)在的一些互聯(lián)網(wǎng)企業(yè)現(xiàn)在也是這么做的。不過要想做好這一點(diǎn)并不容易,30多年的程序員都是“精英”,而那時(shí)候我們的軟件產(chǎn)業(yè)規(guī)模也不大,這些精英足以支撐這個(gè)行業(yè)。而隨著信息化的發(fā)展,軟件產(chǎn)業(yè)的規(guī)模已經(jīng)擴(kuò)大了萬倍了,我們現(xiàn)在無法保證軟件開發(fā)人員都是能寫算法來解決復(fù)雜問題的“精英”,那么我們就只能容忍應(yīng)用系統(tǒng)存在不合理的架構(gòu),不合理的設(shè)計(jì),存在大量比較爛的SQL了。
這種情況下,就需要數(shù)據(jù)庫系統(tǒng)能夠補(bǔ)上應(yīng)用比較爛的短板。實(shí)際上這幾十年數(shù)據(jù)庫廠商的目標(biāo)也是盡可能讓應(yīng)用開發(fā)變得更加簡單,讓應(yīng)用開發(fā)者僅僅關(guān)注與業(yè)務(wù)邏輯。而DBA就是數(shù)據(jù)庫與應(yīng)用開發(fā)者之間的橋梁,他們通過優(yōu)化數(shù)據(jù)庫本身的配置,或者在數(shù)據(jù)庫中采用數(shù)據(jù)庫的手段去優(yōu)化SQL,讓數(shù)據(jù)庫能夠充分的利用底層的系統(tǒng)資源,跑得更加流暢。
舉個(gè)例子,為什么SQL都可以通過開發(fā)修改,還需要在數(shù)據(jù)庫中提供hint,outlines,sql profile ,sql baseline等優(yōu)化手段呢?實(shí)際上這些SQL優(yōu)化技術(shù)的實(shí)現(xiàn)模式不同,應(yīng)用場景也各有不同。Hint是在應(yīng)明確了某種訪問路徑是最優(yōu)的情況下固化SQL執(zhí)行計(jì)劃的方法,可以最有效的解決SQL執(zhí)行計(jì)劃錯(cuò)誤的問題。不過當(dāng)臨時(shí)發(fā)現(xiàn)系統(tǒng)存在SQL執(zhí)行計(jì)劃錯(cuò)誤的時(shí)候,修改應(yīng)用可能至少需要幾個(gè)小時(shí),而業(yè)務(wù)系統(tǒng)需要立即恢復(fù)的時(shí)候,我們就可以使用outlines,在不修改應(yīng)用的前提下強(qiáng)制指定SQL的訪問路徑。
似乎hint/outlines已經(jīng)能夠解決靜態(tài)和動態(tài)兩方面的問題了,二者組合應(yīng)該夠用了吧。事實(shí)上還不夠,因?yàn)橛行r(shí)候某條SQL在代入不同參數(shù)的時(shí)候,有兩種截然不同的最佳訪問路徑,那么使用hint/outlines來固化為某種訪問方式就不合適了,因?yàn)闊o論如何,都會出現(xiàn)一種錯(cuò)誤的執(zhí)行計(jì)劃。這個(gè)時(shí)候,就需要使用sql profile來解決這個(gè)問題了,你可以通過sql profile來讓SQL PLAN生成得更加合理,而不是簡單的指定某種執(zhí)行計(jì)劃。
實(shí)際上,前陣子有個(gè)數(shù)據(jù)庫廠商的研發(fā)人員與我探討過這個(gè)問題,他們的產(chǎn)品已經(jīng)支持了hint和outlines,正在糾結(jié)是不是要支持類似Oracle SQL PROFILE的功能,他們覺得有了前者SQL PROFILE似乎用處不是很大了。
實(shí)際上又回到了本文開頭我們探討的那個(gè)問題了,在實(shí)際的應(yīng)用場景中,解決某些問題的時(shí)候,總是會受到某種限制,因此用戶需要有更多的方案選擇,才能在實(shí)際工作中用最小的代價(jià)來解決問題。有些時(shí)候,解決問題的方法土了一點(diǎn),可能在某些DBA眼里缺乏技術(shù)高度,不過也沒關(guān)系,好用就行,能解決問題就行。