前言
对于一个很大的分区表惊喜update,delete,想要加快执行速度,可以按照分区,在不同的会话中对每个分区表单独进行update,delete。但是对一个很大的非分区表进行update,delete,如果只在一个会话里运行sql,很容易引起undo不够,如果会话连接中断,会导致大量数据从undo回滚,这将是一场灾难!
解决方法
对于非分区表,我们可以对表按照rowid切片,然后开启多个窗口同时执行sql,这样既能加快执行速度,还能减少对undo的占用。
实例
我们对Scott账户下EMP表按照每个extent进行rowid切片
SELECT ' AND ROWID BETWEEN ' || '''' ||
DBMS_ROWID.ROWID_CREATE(1,
B.DATA_OBJECT_ID,
A.RELATIVE_FNO,
A.BLOCK_ID,
0) || '''' || ' AND ' || '''' ||
DBMS_ROWID.ROWID_CREATE(1,
B.DATA_OBJECT_ID,
A.RELATIVE_FNO,
A.BLOCK_ID + A.BLOCKS - 1,
999) || ''';'
FROM DBA_EXTENTS A, DBA_OBJECTS B
WHERE A.SEGMENT_NAME = B.OBJECT_NAME
AND A.OWNER = B.OWNER
AND B.OBJECT_NAME = 'EMP'
AND B.OWNER = 'SCOTT'
ORDER BY A.RELATIVE_FNO, A.BLOCK_ID;
执行结果如下:
假如要执行delete from emp where empno > 50000000,emp表有1亿的数据,
要删除其中5000万行数据, 根据上述方法对表按照rowid切片
delete from emp where empno > 50000000 and ROWID BETWEEN 'AAAR3sAAEAAAACQAAA' AND 'AAAR3sAAEAAAACXAPn';
如果有多个切片, 则在不同的窗口去执行不同的sql语句就可以了。
补充
对字典表赋权
grant select on dba_extents to scott;
grant select on dba_objects to scott;