我们对一些表进行初始批量加载(源和目标都是Oracle 11g)。过程如下:1。截断,2。删除索引(PK和唯一索引),3。批量插入,4。创建索引(再次是PK和唯一索引)。现在我收到以下错误:
alter table TARGET_SCHEMA.MYBIGTABLE
add constraint PK_MYBIGTABLE primary key (MYBIGTABLE_PK)
ORA-01652: unable to extend temp segment by 128 in tablespace TEMP
显然,TEMP表空间对于PK创建来说很小(FYI表有6列,大约22亿条记录)。所以我这样做了:
explain plan for
select line_1,line_2,line_3,line_4,line_5,line_6,count(*) as cnt
from SOURCE_SCHEMA.MYBIGTABLE
group by line_1,line_2,line_3,line_4,line_5,line_6;
select * from table( dbms_xplan.display );
/*
-----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 2274M| 63G| | 16M (2)| 00:05:06 |
| 1 | HASH GROUP BY | | 2274M| 63G| 102G| 16M (2)| 00:05:06 |
| 2 | TABLE ACCESS FULL| MYBIGTABLE | 2274M| 63G| | 744K (7)| 00:00:14 |
-----------------------------------------------------------------------------------------------
*/
这是如何判断创建PK需要多少TEMP表空间(在我的情况下为102 GB)?或者你会以不同的方式进行估算吗?
附加:PK仅存在于目标系统上。但公平点,所以我在目标PK上运行你的查询:
explain plan for
select MYBIGTABLE_PK
from TARGET_SCHEMA.MYBIGTABLE
group by MYBIGTABLE_PK ;
-------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 13 | 3 (34)| 00:00:01 |
| 1 | HASH GROUP BY | | 1 | 13 | 3 (34)| 00:00:01 |
| 2 | TABLE ACCESS FULL| MYBIGTABLE | 1 | 13 | 2 (0)| 00:00:01 |
-------------------------------------------------------------------------------------------
那我现在怎么读这个?
答案 0 :(得分:1)
这是一个很好的问题。
首先,如果您创建以下主键
alter table TARGET_SCHEMA.MYBIGTABLE
add constraint PK_MYBIGTABLE primary key (MYBIGTABLE_PK)
然后你应该查询
explain plan for
select PK_MYBIGTABLE
from SOURCE_SCHEMA.MYBIGTABLE
group by PK_MYBIGTABLE
要估算(请务必收集统计信息exec dbms_stats.gather_table_stats('SOURCE_SCHEMA','MYBIGTABLE')
。
其次,您可以查询V$TEMPSEG_USAGE
以查看在抛出之前消耗了多少临时块,并v$session_longops
查看已完成的整个流程的数量。
Oracle docs建议为进程创建专用的临时表空间,以免干扰任何其他操作。
如果您找到更准确的解决方案,请发布编辑。