Oracle查詢轉(zhuǎn)換器的作用是把原始sql重寫為語義相同的語句,目的是為了獲得更高效的sql。
查詢轉(zhuǎn)換主要有四種技術(shù):子查詢展開,視圖合并,謂詞推入,星型轉(zhuǎn)換。
了解查詢轉(zhuǎn)換是掌握SQL優(yōu)化的基礎(chǔ),本文將對這四種技術(shù)做一些簡單的介紹。
子查詢展開是指優(yōu)化器不再把子查詢作為獨(dú)立的單元處理,而是轉(zhuǎn)換成等價的join方式。轉(zhuǎn)換有兩種方式:一是將子查詢的結(jié)果集作為視圖,與外層表或視圖做join;二是將子查詢中的表或視圖拆出來,與外層表或視圖做join。子查詢前包含以下條件可以被展開:
· any(= any和in等價)
· all(<> all和not in等價)
· exists
· not exists
single row條件(where后面接=,<,>,<=,>=等條件)
子查詢展開的例子:
最終轉(zhuǎn)換的語句:
可以看到子查詢中的dept表被拆出來,與外部查詢塊的emp表做inner join??梢赃@樣轉(zhuǎn)換的前提是dept表的deptno列是唯一鍵。如果deptno列不是唯一鍵,將做semi join(即所謂的半連接):
如果不做子查詢展開,就會走filter類型的執(zhí)行計(jì)劃,并且子查詢放在最后一步執(zhí)行,作用是對emp全表掃描之后的結(jié)果集進(jìn)行過濾:
看一個子查詢結(jié)果集作為內(nèi)聯(lián)視圖與外層查詢塊做join的例子:
執(zhí)行計(jì)劃仍然走了hash join semi,要使得轉(zhuǎn)換是等價的,必須先完成子查詢中departments和locations的join,結(jié)果集作為內(nèi)聯(lián)視圖VM_NSO_1,與外層查詢塊的結(jié)果集做join。
下面的執(zhí)行計(jì)劃中,子查詢的結(jié)果被作為nest loop的驅(qū)動表,為保證結(jié)果集正確,需要對子查詢做hash unique去重。
如果滿足(不限于)下面的條件,子查詢展開可能導(dǎo)致轉(zhuǎn)換不等價,因此將不作展開:
· where后面的連接符為=all或者<> any
· exists后面的子查詢中帶有rownum
· exists后面的子查詢中帶有having子句,cube子句或者rollup子句
例如下面的例子:
視圖合并是指對包含視圖的查詢做出轉(zhuǎn)換,使查詢只包含基表。視圖合并提供了更多的訪問路徑和join的可能性。也就是說,不做視圖合并的執(zhí)行計(jì)劃包含在做了視圖合并的執(zhí)行計(jì)劃中。下面的例子可以幫助理解這句話:
如果不做視圖合并,執(zhí)行計(jì)劃如下:
可以看到不對emp100做視圖合并,執(zhí)行計(jì)劃中出現(xiàn)view字樣,name列對應(yīng)的就是視圖名emp100。
第二個執(zhí)行計(jì)劃除了多了view的一行,訪問路徑和成本是和第一個相同的。
如果視圖定義中包含下列內(nèi)容,將不能做視圖合并:
· 集合操作符(UNION,UNION ALL,INTERSECT,MINUS)
· connect by子句
· rownum偽列
做這些限制是為了防止視圖合并之后得到錯誤的結(jié)果集。
不能視圖合并的例子:
復(fù)雜視圖合并技術(shù)允許對包含gourp by或者distinct的視圖做展開。
_COMPLEX_VIEW_MERGING參數(shù)控制是否激活復(fù)雜視圖合并,在9i之后默認(rèn)為true,同時受OPTIMIZER_FEATURES_ENABLE參數(shù)控制:
使用了外連接的sql中,視圖合并需要滿足下列條件之一:
· 視圖為外連接的驅(qū)動表
· 視圖的定義只包含單表
下例中視圖v1包含兩張基表,在做外連接的驅(qū)動表時發(fā)生視圖合并,做被驅(qū)動表則沒有。
優(yōu)化器在處理不能合并的視圖時,可以選擇將外部查詢的謂詞推入該視圖的查詢塊,或者將視圖中的謂詞拉出到主查詢。這樣更早的處理視圖的結(jié)果集,有可能會減小后續(xù)步驟操作所需的成本。
謂詞推入到視圖內(nèi)部的例子:
注意到執(zhí)行計(jì)劃中條件EMPLOYEE_ID<205被推入到視圖內(nèi)部,將兩張基表各過濾一次,然后對結(jié)果集做union。
兩表關(guān)聯(lián)時,連接條件也可以做推入,先來看不做謂詞推入的執(zhí)行計(jì)劃:
執(zhí)行計(jì)劃中emp13作為驅(qū)動表與departments表做nest loop,我們使用hint強(qiáng)制發(fā)生謂詞推入:
可以看到執(zhí)行計(jì)劃中出現(xiàn)PUSHED PREDICATE字樣,條件e.department_id=d.department_id被轉(zhuǎn)換成等值條件對employees表做過濾。join的謂詞推入往往產(chǎn)生nest loop的執(zhí)行計(jì)劃(驅(qū)動表的每一行驅(qū)動被驅(qū)動表,來做謂詞的過濾)。如果是大數(shù)據(jù)集的sql,可以使用hint no_push_pred或者設(shè)置參數(shù)_push_join_predicate為false禁止謂詞推入。
星型轉(zhuǎn)換為提高星型查詢的效率發(fā)生,在原有條件基礎(chǔ)上會產(chǎn)生新的子查詢對事實(shí)表做過濾,然后通過對事實(shí)表相應(yīng)連接列的位圖索引做位圖操作,達(dá)到過濾事實(shí)表結(jié)果集的目的。
是否開啟星型轉(zhuǎn)換受參數(shù)star_transformation_enabled控制,可以設(shè)置為:
true:優(yōu)化器將考慮基于成本的星型查詢轉(zhuǎn)換;
false:禁止星型轉(zhuǎn)換;
temp_disable:優(yōu)化器將考慮基于成本的星型查詢轉(zhuǎn)換,但是轉(zhuǎn)換中不會使用臨時表。
首先看一下星型轉(zhuǎn)換的例子:
注意到執(zhí)行計(jì)劃首先對各個維度表過濾出結(jié)果集,然后訪問sales表連接列上的索引,做bitmap and操作之后,回表訪問數(shù)據(jù)。事實(shí)上整個過程類似于將查詢轉(zhuǎn)換為如下等價sql:
下面看一下star_transformation_enabled參數(shù)設(shè)置為true的結(jié)果:
注意到執(zhí)行計(jì)劃中先對customers根據(jù)過濾條件cu.country_id =52789得到臨時表SYS_TEMP_0FD9D6601_11F1D1,后續(xù)步驟中每次需要訪問customers表時則由臨時表來替換,這也是為了總共減少所訪問的數(shù)據(jù)量所考慮。
星型轉(zhuǎn)換同樣有一些限制條件,本文暫不討論。
以上是對四類查詢轉(zhuǎn)換概念性的描述,對于具體的應(yīng)用場景中的SQL要具體分析如何利用這些技術(shù)。查詢轉(zhuǎn)換還有諸如子查詢合并,連接因式分解,表擴(kuò)展,表裁剪,物化視圖重寫等技術(shù)。有機(jī)會將再寫文章介紹,或者有興趣的同學(xué)自行研究。
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)cdcxhl.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點(diǎn)與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。
當(dāng)前名稱:Oracle查詢轉(zhuǎn)換初探-創(chuàng)新互聯(lián)
新聞來源:http://aaarwkj.com/article46/dspohg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供動態(tài)網(wǎng)站、外貿(mào)建站、品牌網(wǎng)站設(shè)計(jì)、網(wǎng)站營銷、定制開發(fā)、小程序開發(fā)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容