w*m 发帖数: 1806 | 1 其实说起来很简单,有两张表,
A(a1, a2, a3, a4)
B(b1, b2, b3, b4)
B表大约有30 million记录,A表大概有12万记录
为了加新的速度,我用了下面的script,可是总是出现
ORA-01555: snapshot too old: rollback segment number 1 with name "_SYSSMU1$"
too small
请教大家,这种情况如何改进?包子相赠求解
1. create two indexes for two tables,
create index Ai on A(a1, a2);
create index Bi on B(b1, b2);
2. save the following script as x.sql, and run it,
set SERVEROUTPUT ON
DECLARE
CURSOR v_cursor IS
SELECT a1, a2 FROM A;
total NUMBER :=0;
BEGIN
FOR i IN v_cur |
w*m 发帖数: 1806 | 2 http://space.itpub.net/14209224/viewspace-573125
这篇文章说了一些关于这个错误的解决方法,不过我还是不明白如何解决我的错误。
$"
【在 w*m 的大作中提到】 : 其实说起来很简单,有两张表, : A(a1, a2, a3, a4) : B(b1, b2, b3, b4) : B表大约有30 million记录,A表大概有12万记录 : 为了加新的速度,我用了下面的script,可是总是出现 : ORA-01555: snapshot too old: rollback segment number 1 with name "_SYSSMU1$" : too small : 请教大家,这种情况如何改进?包子相赠求解 : 1. create two indexes for two tables, : create index Ai on A(a1, a2);
|
b******g 发帖数: 81 | 3 怨不得你看不懂呢,这翻译也忒...咋听着跟我儿子说的中文似的。 看看英文解释:
http://www.dba-oracle.com/t_ora_01555_snapshot_old.htm
大意是说你的代码在读数据时有一致性错误。
估计你定义CURSOR时指向A表,UPDATE COMMIT时又是对A表。
你这段SQL必须用到TRANSACTION吗?
【在 w*m 的大作中提到】 : http://space.itpub.net/14209224/viewspace-573125 : 这篇文章说了一些关于这个错误的解决方法,不过我还是不明白如何解决我的错误。 : : $"
|
w*m 发帖数: 1806 | 4 en,我明白这个意思,怎么改呢? 数据量实在是太大了,寸步难行啊
【在 b******g 的大作中提到】 : 怨不得你看不懂呢,这翻译也忒...咋听着跟我儿子说的中文似的。 看看英文解释: : http://www.dba-oracle.com/t_ora_01555_snapshot_old.htm : 大意是说你的代码在读数据时有一致性错误。 : 估计你定义CURSOR时指向A表,UPDATE COMMIT时又是对A表。 : 你这段SQL必须用到TRANSACTION吗?
|
b******g 发帖数: 81 | 5 120K should be fine.
try comment out the if block:
IF MOD(total,100)=0 THEN
...
END IF
I am not sure about Oracle's transaction mechanism, but I suppose change
will put everything in a big transaction block. The final "commit;" will
commit the transaction.
【在 w*m 的大作中提到】 : en,我明白这个意思,怎么改呢? 数据量实在是太大了,寸步难行啊
|
w*m 发帖数: 1806 | 6 10.2.0.4
【在 b******g 的大作中提到】 : 120K should be fine. : try comment out the if block: : IF MOD(total,100)=0 THEN : ... : END IF : I am not sure about Oracle's transaction mechanism, but I suppose change : will put everything in a big transaction block. The final "commit;" will : commit the transaction.
|
b******g 发帖数: 81 | 7 I was thinking something else. Anyway, could you just run the UPDATE:
UPDATE A
SET (A.a3, A.a4)=(SELECT b3, b4 FROM B WHERE A.a1=B.b1 AND A.a2=B.
b2)
Is there any specific reason you want to commit every 100 records?
【在 w*m 的大作中提到】 : 10.2.0.4
|
w*m 发帖数: 1806 | 8 直接update不行,非常非常慢,这是最初的方案。
后来改成加index,每100行 commit 一次。对相对比较小的数据没问题。
可是碰到这个30million数据就不行了。
【在 b******g 的大作中提到】 : I was thinking something else. Anyway, could you just run the UPDATE: : UPDATE A : SET (A.a3, A.a4)=(SELECT b3, b4 FROM B WHERE A.a1=B.b1 AND A.a2=B. : b2) : Is there any specific reason you want to commit every 100 records?
|
b******g 发帖数: 81 | 9 在Explain Plan里先看看你的SQL,看看慢在什么地方。
【在 w*m 的大作中提到】 : 直接update不行,非常非常慢,这是最初的方案。 : 后来改成加index,每100行 commit 一次。对相对比较小的数据没问题。 : 可是碰到这个30million数据就不行了。
|
w*m 发帖数: 1806 | 10 我最后决定用create temp_table as (select*** left join * on ..)去做了。自己测
试了一下,大概30分钟可以完成30million的更新了。下周再到实际项目上测试看看。
【在 b******g 的大作中提到】 : 在Explain Plan里先看看你的SQL,看看慢在什么地方。
|
y****w 发帖数: 3747 | 11 1. 这不是个典型的merge么?
2. 如果因为数据量太大...找你们的dba。或者自己加条件分解成一些小的merge/
update.
3. 索引是必须的。
$"
【在 w*m 的大作中提到】 : 其实说起来很简单,有两张表, : A(a1, a2, a3, a4) : B(b1, b2, b3, b4) : B表大约有30 million记录,A表大概有12万记录 : 为了加新的速度,我用了下面的script,可是总是出现 : ORA-01555: snapshot too old: rollback segment number 1 with name "_SYSSMU1$" : too small : 请教大家,这种情况如何改进?包子相赠求解 : 1. create two indexes for two tables, : create index Ai on A(a1, a2);
|
w*m 发帖数: 1806 | 12 thanks.问题已经解决了。
【在 y****w 的大作中提到】 : 1. 这不是个典型的merge么? : 2. 如果因为数据量太大...找你们的dba。或者自己加条件分解成一些小的merge/ : update. : 3. 索引是必须的。 : : $"
|