兩個超大表做關聯更新的優化
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...