两个超大表做关联更新的优化 之 批量更新
2015-09-15 14:55
519 查看
http://blog.itpub.net/16628454/viewspace-1043225/
两个超大表做关联更新的优化
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个小时,当时开发人员急于要结果,于是我用以前看到的一篇帖子中提到的方法(http://www.itpub.net/thread-1052077-1-7.html)来解决,其实还是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)*/
1
FROM 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)*/
1
FROM 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;
/
两个超大表做关联更新的优化
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个小时,当时开发人员急于要结果,于是我用以前看到的一篇帖子中提到的方法(http://www.itpub.net/thread-1052077-1-7.html)来解决,其实还是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)*/
1
FROM 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)*/
1
FROM 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;
/
相关文章推荐
- Spring MVC json问题(406 Not Acceptable) 解决办法
- Java后台通过JDBC连接数据库
- python paramiko模块实现ssh命令
- 防微信雷达扫描加好友控件实现
- 凭什么苹果设计师年赚110万,把设计几何学融入你的产品中
- Oracle中Rman自动备份数据库 .
- HDU 5443 The Water Problem
- failed to update auto layout status: the agent crashed within Xcode7
- 哪本书是对程序员最有影响、每个程序员都该阅读的书?
- svn导出历史版本
- MediaRecoder(查看api)录制声音
- C++ Pointer-to-Member Selector
- 将Vim配置成为一款强大的编辑工具之 vimrc配置
- url 中文乱码问题
- 如何设计一个像人的大脑皮层一样的产品?
- DB2怎么根据开始和结束时间算相隔天数
- 如何找出长期未被使用的索引
- Maven学习记录1——什么是 Maven
- ISLR系列:(1)线性回归 Linear Regression
- 机器学习实战-第2章(k-近邻算法)