我有一个存储过程,在这里我使用游标在临时表中的项目之间循环:
OPEN CURSOR_SCORE_ITEMS FOR SELECT
ID_X, ID_Y
FROM
SCORE_ITEMS
GROUP BY
ID_X, ID_Y
HAVING
SUM(SCORE) > 10;
LOOP
FETCH CURSOR_SCORE_ITEMS BULK COLLECT INTO COMPARE_ITEMS LIMIT 100;
---loop over items and do stuff---
END LOOP;
CLOSE CURSOR_SCORE_ITEMS;
对于“ SCORE_ITEMS”表较小的实例,该过程运行良好,但是对于大型表(数百万行),我会收到错误消息
“ ORA-01652:表空间TEMP_ALL中的Temp-segment kann nicht um 12800 erweitert werden”
(抱歉,德语)。
请注意,SCORE_ITEMS是一个临时表,该表在此过程的早期生成。似乎光标查询超出了临时表空间的大小。
我已经阅读了一些涉及增加表空间大小的解决方案,但是我对该数据库没有任何特权,因此我认为这是不可能的。我是否可以考虑使用另一种方法或某种预处理来减少temp表空间的开销?
答案 0 :(得分:1)
全局临时表被写入TEMPORARY表空间(即,不是堆表的常规表空间)。您是否有单独的GTT临时表空间?我怀疑不是。大多数地方都不是。
因此(假设否),当SCORE_ITEMS具有数百万行时,您已经吃掉了很大一部分的TEMP。然后,您的查询将以足够大的聚合量开始以溢出到TEMP中-因为GROUP BY需要排序。
您已经排除了明显的解决方案:
增加表空间的大小,但是我对该数据库没有任何特权,所以我认为这是不可能的。
我不知道这是否也排除了与DBA交谈并查看它们是否会增加分配给TEMP的空间的激进想法,或者-更好的是-为Global Temporary Tables创建新的表空间。
要考虑的另一件事是您是否真的需要TEMP_SCORE。人们可以编写更高效的SELECT来填充GTT,这并不稀奇。 GTT有很多开销-磁盘的所有I / O,更不用说争夺共享TEMP表空间了。绝对是可以考虑的选择。