新聞中心
?在和一些國(guó)產(chǎn)數(shù)據(jù)庫(kù)廠商的朋友交流的的時(shí)候,總能聽(tīng)到他們說(shuō)自己的優(yōu)化器是高手設(shè)計(jì)出來(lái)的,充分利用了現(xiàn)代軟硬件技術(shù),因此與Oracle相比只強(qiáng)不弱。我不太贊成這樣的說(shuō)法,因?yàn)橐粋€(gè)優(yōu)秀的優(yōu)化器設(shè)計(jì)能夠做到的只是在大的框架上比較不錯(cuò),針對(duì)一些常規(guī)的SQL語(yǔ)句比較有效,而SQL語(yǔ)句的復(fù)雜性往往遠(yuǎn)遠(yuǎn)超出數(shù)據(jù)庫(kù)設(shè)計(jì)人員的想象,我們的數(shù)據(jù)庫(kù)廠商也往往低估了開(kāi)發(fā)人員寫(xiě)SQL的能力。那些天馬行空的神來(lái)之筆,會(huì)讓再優(yōu)秀的優(yōu)化器都感到力不從心。

宿松網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián),宿松網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為宿松數(shù)千家提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\成都外貿(mào)網(wǎng)站建設(shè)公司要多少錢(qián),請(qǐng)找那個(gè)售后服務(wù)好的宿松做網(wǎng)站的公司定做!
前些年一個(gè)朋友在做一個(gè)數(shù)據(jù)庫(kù)遷移的時(shí)候遇到一條SQL的性能問(wèn)題,這條SQL在Oracle上執(zhí)行的效率很不錯(cuò),但是到了一個(gè)基于PG的國(guó)產(chǎn)數(shù)據(jù)庫(kù)上,就慢得讓人受不了了。我們通過(guò)一個(gè)簡(jiǎn)單的測(cè)試案例來(lái)復(fù)現(xiàn)這個(gè)問(wèn)題。
用戶現(xiàn)場(chǎng)是一個(gè)內(nèi)網(wǎng)系統(tǒng),因此我們只能采用模仿的方式來(lái)給大家復(fù)一復(fù)盤(pán)。我們用dba_objects和dba_tables兩個(gè)系統(tǒng)視圖來(lái)創(chuàng)建兩張物理表。然后執(zhí)行這條語(yǔ)句:
Oracle DBA看到這條SQL會(huì)覺(jué)得十分不解,為啥能寫(xiě)出這樣的SQL語(yǔ)句來(lái)呢?程序員的大腦DBA是很難理解的。就是不知道我們的數(shù)據(jù)庫(kù)廠商懂不懂了。不過(guò)實(shí)際應(yīng)用場(chǎng)景中我們確實(shí)經(jīng)常遇到這樣的奇葩SQL。
我們?cè)赑G數(shù)據(jù)庫(kù)上做一個(gè)類似的測(cè)試用例,我們使用PG_TABLES、PG_INDEXES這兩個(gè)視圖來(lái)創(chuàng)建t1/t2表。
保險(xiǎn)起見(jiàn),建完表后我們做一次vacuum analyze。然后看看這條SQL的執(zhí)行計(jì)劃如何:
這條SQL貌似執(zhí)行速度還行,不過(guò)實(shí)際上真實(shí)環(huán)境的數(shù)據(jù)是不同的。我們從執(zhí)行計(jì)劃上來(lái)看看會(huì)有些什么問(wèn)題。首先在T2表上是做了一個(gè)根據(jù)掃描,查到一個(gè)數(shù)組,這個(gè)被定義為SubPlan1,然后對(duì)T1表做掃描,通過(guò)SubPlan1的結(jié)果做過(guò)濾,獲得最終的數(shù)據(jù)。這個(gè)執(zhí)行計(jì)劃的問(wèn)題實(shí)際上是十分明顯的,當(dāng)T1/T2表很大的時(shí)候,這個(gè)查詢會(huì)變得很慢。比如我們?cè)黾覶2的大小到幾萬(wàn)條記錄。
可以看到,PG的執(zhí)行計(jì)劃變成了在T2表上通過(guò)索引掃描,這是優(yōu)化器做了有效的優(yōu)化。我們用同樣的方法擴(kuò)大T2表,到幾十萬(wàn)條記錄,看看會(huì)有什么情況。
執(zhí)行計(jì)劃還是如此,而執(zhí)行時(shí)間已經(jīng)加大到400多毫秒了。如果數(shù)據(jù)庫(kù)的IO性能有點(diǎn)問(wèn)題,并且t1表十分巨大,那么這個(gè)執(zhí)行計(jì)劃肯定就會(huì)有問(wèn)題了。實(shí)際生產(chǎn)環(huán)境中就是因?yàn)閿?shù)據(jù)量較大,才出現(xiàn)了性能問(wèn)題。
我們?cè)賮?lái)看看Oracle的執(zhí)行計(jì)劃,可以看出這兩個(gè)執(zhí)行計(jì)劃之間的差異是很大的。
Oracle的執(zhí)行計(jì)劃采用了一個(gè)Hash 半連接,通過(guò)兩次索引掃描獲得半連接的兩個(gè)半?yún)^(qū)數(shù)據(jù),然后用HASH UNIQUE探測(cè)內(nèi)表數(shù)據(jù)。做一個(gè)10053 trace我們可以看到,Oracle在編譯這條SQL的時(shí)候,做了多種FPD和轉(zhuǎn)換的分析,最終才找到了這個(gè)最優(yōu)解。如果對(duì)這個(gè)分析過(guò)程感興趣的朋友可以自己做個(gè)10053看看,這里篇幅有限我就不做詳細(xì)的介紹了,整個(gè)trace文件接近6000行。
這個(gè)執(zhí)行計(jì)劃可以說(shuō)是沒(méi)有太大毛病的,通過(guò)兩個(gè)索引避免了兩張大表的全表掃描,通過(guò)Hash半連接確保了整個(gè)JOIN的總體規(guī)??煽?。
一個(gè)優(yōu)秀的數(shù)據(jù)庫(kù)產(chǎn)品,其優(yōu)化器一定會(huì)隨著應(yīng)用規(guī)模的擴(kuò)大,遇到的奇葩SQL越多而變得越來(lái)越強(qiáng)大的。如果我們總是告訴用戶,你不應(yīng)該這么寫(xiě)SQL,而不從優(yōu)化器的角度去解決這些奇葩SQL的性能問(wèn)題,那么我們的進(jìn)步就會(huì)變得太慢,我們與Oracle的技術(shù)差距就會(huì)越來(lái)越大。
對(duì)于這個(gè)案例,前陣子我正好和一家國(guó)產(chǎn)數(shù)據(jù)庫(kù)廠商做過(guò)一些交流。他們的老版本中的執(zhí)行計(jì)劃也不是很好。
當(dāng)時(shí)我和廠商的朋友分析他們的執(zhí)行計(jì)劃的時(shí)候,我認(rèn)為雖然在T2的TABLE SCAN上做了LIMIT(1)的過(guò)濾,但是如果符合條件的記錄位于一張大表的最后幾行,那么這個(gè)掃描的成本會(huì)很高。并且最致命的是Nested loop Join Cartestan這個(gè)算子,如果T1符合條件的數(shù)據(jù)比較多,那么這條SQL的執(zhí)行效率將會(huì)特別低,甚至幾個(gè)小時(shí)執(zhí)行不出來(lái)。
最近我測(cè)試了他們的最新版本的產(chǎn)品,讓我感到了新版本在優(yōu)化器方面的能力提升還是比較大的。
當(dāng)表的數(shù)據(jù)量不大的時(shí)候,執(zhí)行計(jì)劃通過(guò)對(duì)兩個(gè)索引的掃描,然后做MERGE半連接。
數(shù)據(jù)量較大的時(shí)候,執(zhí)行計(jì)劃改走了Hash 右半連接,與Oracle的執(zhí)行計(jì)劃不同的是,對(duì)較小的表T1采用了全表掃描的模式。
雖然在這個(gè)執(zhí)行計(jì)劃上還有一些可以商榷的地方,不過(guò)不同的數(shù)據(jù)庫(kù)因?yàn)閷?duì)全表掃描的成本的計(jì)算不同,因此可能會(huì)有不同的選擇。從兩個(gè)版本的執(zhí)行計(jì)劃的優(yōu)化效果上,我們也看到了國(guó)產(chǎn)數(shù)據(jù)庫(kù)在核心能力方面的進(jìn)步。這種進(jìn)步恐怕只能在不斷的實(shí)踐中才能磨練出來(lái)。因此我們也有理由相信,隨著數(shù)據(jù)庫(kù)信創(chuàng)工作的不斷深入,我們的數(shù)據(jù)庫(kù)產(chǎn)品也會(huì)越來(lái)越好的。?
當(dāng)前題目:優(yōu)秀的優(yōu)化器是在實(shí)踐中磨練出來(lái)的
網(wǎng)站URL:http://fisionsoft.com.cn/article/dhcsdii.html


咨詢
建站咨詢
