从游标读取时发生ORA-01652错误

时间:2019-04-08 08:43:44

标签: sql oracle plsql tablespace

我有一个存储过程,在这里我使用游标在临时表中的项目之间循环:

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表空间的开销?

1 个答案:

答案 0 :(得分:1)

全局临时表被写入TEMPORARY表空间(即,不是堆表的常规表空间)。您是否有单独的GTT临时表空间?我怀疑不是。大多数地方都不是。

因此(假设),当SCORE_ITEMS具有数百万行时,您已经吃掉了很大一部分的TEMP。然后,您的查询将以足够大的聚合量开始以溢出到TEMP中-因为GROUP BY需要排序。

您已经排除了明显的解决方案:

  

增加表空间的大小,但是我对该数据库没有任何特权,所以我认为这是不可能的。

我不知道这是否也排除了与DBA交谈并查看它们是否会增加分配给TEMP的空间的激进想法,或者-更好的是-为Global Temporary Tables创建新的表空间。

要考虑的另一件事是您是否真的需要TEMP_SCORE。人们可以编写更高效的SELECT来填充GTT,这并不稀奇。 GTT有很多开销-磁盘的所有I / O,更不用说争夺共享TEMP表空间了。绝对是可以考虑的选择。