oracle中sum和count可以嵌套吗_【分享吧】Oracle查询转换
前言
“查詢(xún)轉(zhuǎn)換”是Oracle解析SQL語(yǔ)句中重要的步驟。其原理是Oracle在解析時(shí)通過(guò)對(duì)原有SQL的等價(jià)改寫(xiě),以達(dá)到較高執(zhí)行效率的方式。
上圖展示了SQL的執(zhí)行過(guò)程,當(dāng)客戶(hù)提交的語(yǔ)句經(jīng)過(guò)解析后,在提交給優(yōu)化器之前會(huì)進(jìn)行一個(gè)查詢(xún)轉(zhuǎn)換的步驟。在這個(gè)步驟中,Oracle會(huì)根據(jù)一些規(guī)則來(lái)決定對(duì)目標(biāo)SQL進(jìn)行查詢(xún)轉(zhuǎn)換。根據(jù)處理方式的不同,查詢(xún)轉(zhuǎn)換可以分為兩類(lèi):
?????? 1、基于規(guī)則的查詢(xún)轉(zhuǎn)化,即當(dāng)滿(mǎn)足規(guī)則定義的條件時(shí),對(duì)語(yǔ)句進(jìn)行相應(yīng)的轉(zhuǎn)化。
?????? 2、基于成本的查詢(xún)轉(zhuǎn)化,即比較轉(zhuǎn)換前后的SQL成本,當(dāng)?shù)葍r(jià)改寫(xiě)SQL的成本小于原始SQL成本時(shí),進(jìn)行SQL轉(zhuǎn)化。
常見(jiàn)的查詢(xún)轉(zhuǎn)化有:子查詢(xún)類(lèi)、視圖類(lèi)、謂詞類(lèi)等。通過(guò)以下實(shí)例,對(duì)常用的查詢(xún)轉(zhuǎn)化進(jìn)行說(shuō)明。
01
子查詢(xún)類(lèi)
子查詢(xún)是SQL中常用的寫(xiě)法,優(yōu)化器對(duì)會(huì)對(duì)子查詢(xún)提前進(jìn)行評(píng)估,使得優(yōu)化器可以更早地介入優(yōu)化,已獲得更優(yōu)質(zhì)的執(zhí)行計(jì)劃。
1、準(zhǔn)備兩張表,在子表上創(chuàng)建索引。
2、通過(guò)提示PUSH_SUBQ/NO_PUSH_SUBQ對(duì)優(yōu)化的子查詢(xún)轉(zhuǎn)換進(jìn)行控制,不使用查詢(xún)轉(zhuǎn)換,從執(zhí)行計(jì)劃可見(jiàn),出現(xiàn)了FILTER關(guān)鍵字,這是指執(zhí)行按照T_OBJECTS和T_USERS進(jìn)行了一個(gè)索引的嵌套循環(huán),效率較低。
3、不使用提示,通過(guò)執(zhí)行計(jì)劃可看出沒(méi)有出現(xiàn)兩表嵌套,而是提前處理了子查詢(xún),先生成了MAX CREATED,然后全表掃描T_OBJECTS進(jìn)行過(guò)濾,顯然這種方式效率更高。
02
視圖類(lèi)
在視圖類(lèi)的查詢(xún)轉(zhuǎn)換中最常用的就是視圖合并,是指優(yōu)化器將視圖定義的語(yǔ)句進(jìn)行拆解,不作為整體執(zhí)行,而是將其定義的語(yǔ)句與外部查詢(xún)合并起來(lái),再由優(yōu)化器選擇執(zhí)行計(jì)劃。
1、創(chuàng)建一個(gè)帶有過(guò)濾條件的視圖,并對(duì)這個(gè)視圖進(jìn)行帶過(guò)濾條件的查詢(xún)。在執(zhí)行計(jì)劃中可以看出已經(jīng)沒(méi)有視圖對(duì)象出現(xiàn)。視圖內(nèi)部的過(guò)濾條件OWNER=’SYS’和外部的過(guò)濾條件OBJECT_ID=10都被合并在一起并轉(zhuǎn)換為基表T_OBJECTS的過(guò)濾條件。
2、同修改隱含參數(shù),不允許進(jìn)行簡(jiǎn)單視圖的合并。從執(zhí)行計(jì)劃中可以看到出現(xiàn)“VIEW”字樣,即沒(méi)有進(jìn)行視圖合并。
03
謂詞類(lèi)
謂詞是指SQL語(yǔ)句中WHERE部分對(duì)數(shù)據(jù)過(guò)濾條件。Oracle優(yōu)化器會(huì)將SQL語(yǔ)句中謂詞的整體考慮,進(jìn)行謂詞轉(zhuǎn)化。例如:如果存在視圖,可以將視圖外部的過(guò)濾條件推入視圖中,這樣做可以盡早過(guò)濾數(shù)據(jù),提高查詢(xún)效率。
1、新建一個(gè)帶有過(guò)濾條件的視圖,然后進(jìn)行查詢(xún)。我們看到執(zhí)行計(jì)劃沒(méi)有看到謂詞推入,原因是這里采用了前面說(shuō)的到視圖合并。
2、使用no_merge提示后我們看到在ID=1的步驟里可以看到VIEW字樣,即視圖沒(méi)有進(jìn)行合并。再看一下ID=2的步驟,由Predicate Information可見(jiàn),過(guò)濾條件是STATUS=‘VALID’ AND OBJECT_ID=20。可見(jiàn)這里的條件不僅包括視圖定義中對(duì)表的過(guò)濾條件,還包括了從外部傳入的過(guò)濾條件。即過(guò)濾謂詞被推入了視圖定義中。
04
消除類(lèi)
消除類(lèi)是指優(yōu)化器在生成執(zhí)行計(jì)劃之前通過(guò)分析,省略SQL中的部分內(nèi)容。當(dāng)然消除前后的SQL語(yǔ)句一定是等價(jià)的。
1、排序消除,是指在優(yōu)化器再生成執(zhí)行計(jì)劃前,將語(yǔ)句中沒(méi)有必要的排序操作消除,避免在執(zhí)行計(jì)劃中出現(xiàn)排序操作或由排序?qū)е碌牟僮鳌?/p>
看下面查詢(xún)語(yǔ)句中的排序不是必須的,從Statistics的Sorts部分可以看出都是0,可以看出優(yōu)化器在生成執(zhí)行計(jì)劃時(shí),對(duì)排序進(jìn)行了消除。
2、去重消除,是指如果語(yǔ)句中對(duì)象存在主鍵或唯一約束,那么語(yǔ)句中的DISTINCT是可以消除的。
新建一張表,進(jìn)行DISTINCT查詢(xún)。通過(guò)下面的執(zhí)行計(jì)劃,可以看到默認(rèn)走了全面掃描,然后用HASH進(jìn)行了去重。
通過(guò)給T_USERS增加唯一索引后,再進(jìn)行查詢(xún)。通過(guò)執(zhí)行計(jì)劃可以看出是直接通過(guò)新增榆樹(shù)UK_USERNAME的索引完成了掃描,不需要再去重了。
3、表消除,是指兩表關(guān)聯(lián)且存在主外鍵關(guān)系時(shí),優(yōu)化器可以消除不必要的表訪問(wèn)以提高效率。
首先創(chuàng)建T_TABLES、T_TABLESPACES兩張表,并創(chuàng)建他們之間的外鍵關(guān)系,并對(duì)T_TABLES進(jìn)行查詢(xún)。雖然SQL中關(guān)聯(lián)到了T_TABLESPACES,但其實(shí)是不需要的。所以通過(guò)執(zhí)行計(jì)劃可以看到優(yōu)化器對(duì)T_TABLESPACE進(jìn)行了消除。
除了以上介紹的查詢(xún)轉(zhuǎn)換,Oracle優(yōu)化器還會(huì)對(duì)OR、LIKE、IN、BETWEEN、NOT、常量等進(jìn)行查詢(xún)轉(zhuǎn)換,以生成更加合理的的執(zhí)行計(jì)劃,提高查詢(xún)效率。希望通過(guò)對(duì)Oracle查詢(xún)轉(zhuǎn)換的介紹,能讓大家對(duì)Oracle優(yōu)化有更進(jìn)一步的了解。
總結(jié)
以上是生活随笔為你收集整理的oracle中sum和count可以嵌套吗_【分享吧】Oracle查询转换的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: sql 触发器_一键生成某个sql的ht
- 下一篇: set-cookie 和 cookie