兩個超大表做關聯更新的優化 之 批量更新

2021-07-05 07:33:47 字數 3166 閱讀 8419

兩個超大表做關聯更新的優化

2010-12-17 13:43:01

分類: oracle

今天同事給了兩個sql,超級大,乙個表8000多萬,乙個表7800萬,原語句如下:

[@more@]

update channel_chengdu.o_user_cons partition(p201011) a

set unuser_flag = (select unuser_flag

from channel_chengdu.o_user partition(p201011) b

where a.serv_id = b.serv_id)

where exists (select 1

from channel_chengdu.o_user partition(p201011) b

where a.serv_id = b.serv_id);

update channel_chengdu.o_user_cons partition(p201011) a

set bill_user_flag = (select bill_user_flag

from channel_chengdu.o_user partition(p201011) b

where a.serv_id = b.serv_id)

where exists (select 1

from channel_chengdu.o_user partition(p201011) b

where a.serv_id = b.serv_id);

這兩條語句在執行第一條的時候執行了6個小時沒出結果,就被殺掉了,光回滾就用了2個小時,當時開發人員急於要結果,於是我用以前看到的一篇帖子中提到的方法(來解決,其實還是bulk connect,第一條語句跑了899秒,第二條跑了708秒。經過開發人員的邏輯驗證,結果是正確的,但我始終對業務邏輯產生懷疑,不過這是後話,畢竟自己對應用不了解,好吧,看下改後的語句。

-----執行了889秒

declare

maxrows number default 5000;

row_id_table dbms_sql.urowid_table;

p_id_table dbms_sql.number_table;

cursor acnt_first_cur is

select /* use_hash(a,b) parallel(a 4) parallel(b 4) */

b.unuser_flag, b.rowid row_id

from channel_chengdu.o_user partition(p201011) b,

channel_chengdu.o_user_cons partition(p201011) a

where a.serv_id = b.serv_id

and exists (select /*+use_hash(c,d) parallel(c 4) parallel(d 4)*/

1from channel_chengdu.o_user partition(p201011) c,

channel_chengdu.o_user_cons partition(p201011) d

where c.serv_id = d.serv_id)

order by b.rowid;

begin

open acnt_first_cur;

loop

exit when acnt_first_cur%notfound;

fetch acnt_first_cur bulk collect

into p_id_table, row_id_table limit maxrows;

forall i in 1 .. row_id_table.count

update channel_chengdu.o_user_cons partition(p201011)

set unuser_flag = p_id_table(i)

where rowid = row_id_table(i);

commit;

end loop;

end;

/-----708秒

declare

maxrows number default 5000;

row_id_table dbms_sql.urowid_table;

p_id_table dbms_sql.number_table;

cursor acnt_first_cur is

select /* use_hash(a,b) parallel(a 4) parallel(b 4) */

b.bill_user_flag, b.rowid row_id

from channel_chengdu.o_user partition(p201011) b,

channel_chengdu.o_user_cons partition(p201011) a

where a.serv_id = b.serv_id

and exists (select /*+use_hash(c,d) parallel(c 4) parallel(d 4)*/

1from channel_chengdu.o_user partition(p201011) c,

channel_chengdu.o_user_cons partition(p201011) d

where c.serv_id = d.serv_id)

order by b.rowid;

begin

open acnt_first_cur;

loop

exit when acnt_first_cur%notfound;

fetch acnt_first_cur bulk collect

into p_id_table, row_id_table limit maxrows;

forall i in 1 .. row_id_table.count

update channel_chengdu.o_user_cons partition(p201011)

set bill_user_flag = p_id_table(i)

where rowid = row_id_table(i);

commit;

end loop;

end;/

兩個不同庫的兩個表關聯後批量更新資料

有兩個表可以通過某個字段進行關聯,想要在乙個表中能夠查詢兩個表的資料的對應關係,但是這兩個表又在不同的庫中,查詢比較麻煩,所以需要批量更新乙個表中的乙個字段用來記錄關聯關係。可以對其中乙個表進行批量洗資料 將某乙個表匯入到另乙個表所在的庫中 然後執行批量更新的sql即可 update table1 ...

ORACLE 兩個表之間更新的實現

前提條件 表info user中有字段id和name,欄位id為索引 表data user info中有字段id和name,欄位id為索引 其中表info user中欄位id和表data user info中欄位id數值一致。要求實現 更新表info user中的字段name 與表data user...

資料結構中 兩個表的關聯 表的主鍵

在現實的資料庫應用中,資料儲存在多個相關聯的表中。基本上沒有資料只存在乙個表中的情況。小的應用系統一般也有十幾個表,大型系統一般有上千個表。我們以學生成績查詢為例來講解表的關聯。除了student表,這裡我們需要新建成績表,表grade snocno grade s01c01 s01c04 s02c...