2012-08-31 44 views
0

我有兩個選項可以根據選擇查詢的遊標更新表。Oracle Bulk從光標或用戶處收集和更新使用Select子查詢進行更新

說我有這個選擇查詢:

select id1 from table1 

和我的更新查詢:

update table2 set value=1 where table2.id2 = table1.id1 

現在的2個選項是:

  1. 設置光標選擇查詢並批量獲取它,然後在for all語句中激發更新查詢。與選擇的子查詢作爲

  2. 寫入更新查詢:

    更新表2的設定值= 1,其中在table2.id2(選擇從表1 ID1)

哪一個更好?

Oracle在內部是否將select子查詢轉換爲批量收集,還是將其視爲普通光標?

回答

1

首先對您的問題「Oracle是否將select子查詢內部轉換爲批量收集?」
否。優化程序計算一個計劃並以某種適當的方式從子查詢中選擇數據。沒有涉及批量收集。

你的問題「哪一個更好?」。這得看情況。如果你可以制定一個查詢得到所有你的table1.id1在一次運行 table2有很多行,所以subselect是昂貴的,那麼我可能會使用批量收集。但請記住,根據數據量的不同,您需要一些PGA才能完成此操作。

但我可以指向另一個 - 恕我直言很優雅 - 解決方案:

MERGE INTO table2 
    USING (select id1 from table1) 
    ON (id2 = id2) 
    WHEN MATCHED THEN 
    UPDATE SET value=1 
; 

這通常快於做子查詢和比散裝更快收集:表1上一次運行和對錶2的一個運行。 (根據需要添加where子句)

+0

「首先問你的問題」Oracle是否將select子查詢內部轉換爲批量收集?「否」。說實話這是不正確的。嘗試FOR rec IN select使用dbms_profiler,你會看到有隱含的5行左右的散列:) –

+0

@AlexanderTokarev:我不明白你的觀點。 'FOR rec IN select'顯然是FOR循環的批量收集。問題是'update table2 set value = 1 where table2.id2 in(select 1 from table1)'並且沒有涉及批量收集。 PL/SQL'FOR .. LOOP'不是子查詢。 – GWu

+0

我明白你的觀點。稍微困惑:)錯過了SUBQUERY字:) –