Oracle中的查詢轉換簡介(上)

2021-08-02 04:54:43 字數 3473 閱讀 1657

oracle查詢轉換的概念:

oracle在解析目標sql時可能會對其對其做等價改寫,目的是為了更高效的自行目標sql,即oracle可能會將目標改寫成語義上完全等價的但執行效率更高的形式。

oracle查詢轉換的型別有如下:

子查詢展開

檢視合併: 簡單檢視合併 外連線檢視合併 複雜檢視合併

星型連線轉換

連線謂詞推入

連線因式分解

表擴充套件

表移除

oracle處理sql中語句中in:

in list iterator

in list expansion /or expansion

in list filter

對in做子查詢展開、檢視合併

以下分別簡單解釋:

子查詢展開:

優化器處理還有子查詢的目標sql的一種優化手段。它是指不再將子查詢作為乙個單獨的整體來處理,而是將其轉化為自身和外部查詢之間等價的表連線。

分為兩種情況:一種是將子查詢展開; 一種是不拆開但是把子查詢轉為乙個內嵌的檢視,再和外部的表,檢視做連線。

如果不做子查詢展開,那麼通常的執行計畫是,這個子查詢在目標sql的最後一步才執行,並且會走filter型別的執行計畫。

oracle能否做子查詢展開取決下面兩個條件:

子查詢展開所對應的sql在語義上應該和原sql完全等價。否則便不能進行子查詢展開(這是理所當然的條件)

對於子查詢不展開,而轉為乙個內嵌試圖的子查詢展開,只有當經過子查詢展開後的等價改寫sql的成本值小於原sql的成本值,才會進行此類的子查詢展開。

對於子查詢展開的第一種情形,oracle始終會對其進行子查詢展開,而不管經過子查詢展開後的sql的成本值是否小於原sql的成本值。
oracle並不對所有的子查詢進行子查詢展開,它還有前提條件的,也就是滿足了這些條件,才可能考慮進行子查詢展開。

oracle資料庫裡子查詢前的where條件如果是如下這些條件之一,那麼這種型別的目標sql在滿足了一定條件之後就可以做子查詢展開:

single-row (即 = < > <= >= 和<>)

exists

not exists

in not in

any

all

select t.userid, wm_concat(r.standno) as standno

from tb_productctrl_usertaskinfo t, (select * from tb_productctrl_linetaskinfo where ownerworkshop = # ) r

where t.taskclose = 'n'

and t.taskstatus = 'n'

and trunc(t.senddate, 'dd') > sysdate - 2

and r.soflseqnr = t.tasksoflseqnr

group

by t.userid

上述sql裡面也有子查詢,但是oracle不會進行子查詢展開,因此子查詢會以filter執行計畫的方式,在最後一步出現。

下面這樣寫就可以進行子查詢展開了, 下面的sql去掉了這個值 wm_concat(r.standno) as standno,是為了方便說明子查詢展開限制條件的問題。 這個sql在業務中是不需要子查詢就可以完成的。

檢視合併:檢視合併是oracle處理帶有檢視的sql的一種優化手段。它的基本原理也是不再將視做為乙個單獨的檢視來處理,而是將其拿出來和外部查詢合併。

檢視合併分為三種型別:簡單檢視合併,外連線檢視合併,複雜檢視合併。對於簡單檢視合併,只要符合進行簡單檢視合併的條件,oracle始終會對其做檢視合併,而不管經過檢視合併後的等價改寫sql的成本值是否小於原sql的成本值。對於複雜檢視合併,只有等價改寫後的sql的成本值小於原sql的成本值時,oracle才會對目標sql進行複雜檢視合併。

oracle做簡單檢視合併後的等價改寫只是讓優化器有了更多的執行路徑可以選擇,原來的未做簡單檢視合併情形下的執行路徑還是保留了,所以做了簡單檢視合併後等價改寫sql的成本值一定小於等於未做簡單檢視合併的原sql的成本值。

**這個和子查詢展開的第一張情況並不一樣,oracle始終會做子查詢展開,但是展開後存在成本值大於原sql成本值的情況。**
oracle進行簡單檢視合併的條件:

檢視定義中

不包括外連線,

不包含distinct group by等聚合函式,

不包含集合運算子:union all union intersect (表是兩個表的交集) minus (a-b)

不包含:connect by子句

不包含: rownum

……外連線檢視合併:

用來處理使用了外連線,以及檢視定義中不存在distinct group byu等聚合函式的sql。

oracle做外連線檢視合併的條件:

當目標檢視在和外部查詢的表做外連線時,該目標檢視可以做外連線檢視合併的條件是:

要麼該檢視作為外連線的驅動表。當該檢視作為外連線的被驅動表時,他的檢視定義只能包含乙個表。

外連線的驅動表,左連線就是左表,右連線就是右表,也就是不增加null行的表。

複雜檢視合併:

複雜檢視合併就是來處理檢視定義總包含distinct group by的語句。

複雜檢視合併的基本原理就是推遲執行distinct 或者group by。但是推遲執行distinct 或者group by並不一定能提公升執行效率,因為可能distinct 或者group by會過濾掉大部分資料。

因為複雜檢視合併並不一定提公升oracle效率的提公升,只有當經過複雜檢視合併後等價改寫sql的成本值小於原sql的成本值時,oracle才會對目標sql執行複雜檢視合併。

oracle 查詢轉換

1 子查詢展開 single row exists,not exists,in,not in,any,all 不能做子查詢展開的通常會在sql執行計畫最後一步才執行,一般是filter型別計畫,效率很差 in exists,any 可轉換為半連線 semi join not in,not exist...

Oracle中的時區轉換

在下面找到一些有關oracle中時區轉換的有用資訊。希望這對他們中的許多人有所幫助,因為我們從事的所有實時專案都遵循不同的時區 est,pst等 您可能需要根據需要將它們轉換為特定的專案 insert into dates values 6,to date 09 20 05 23 15 mm dd ...

Oracle中的轉換函式

oracle中的轉換函式有三個,分別為to char to date to number 1 to char 的用法 格式化當前的日期時間 select sysdate,to char sysdate,yyyy mm dd from dual select sysdate,to char sysda...