oracle查询 - ORA-01652:无法扩展临时段,但只能在某些版本的sql*plus中扩展

sym*_*ean 5 linux oracle client sqlplus ora-01652

这个让我很困惑.我编写了一个从我的开发客户端运行良好的查询但在生产客户端上失败并出现错误"ORA-01652:无法扩展临时段......".在这两种情况下,数据库和用户都是相同的.在我的开发机器(MS Windows)上,我有SQL*PLUS(版本9.0.1.4.0)和Toad 9.0(都使用了oci.dll的9.0.4.0.1版本).两者都运行代码没有错误.

但是,当我在同一个数据库上运行相同的文件时,使用来自不同机器的相同用户名/密码,这次版本10.2.0.4.0(来自10.2.0.4-1 Oracle即时客户端)我收到错误.

它确实可重复发生.

不幸的是,我只能访问数据库上的字典视图,这些视图设置为只读(甚至无法获得解释计划!).

我试过通过调整查询来解决这个问题(我怀疑有一个大的中间结果集随后被修剪掉了)但是没有设法改变任何一个客户端的行为.

有可能在计算机上部署不同版本的客户端导致问题 - 但目前看起来像是降级到以前的版本.

有任何想法吗?

TIA

更新

根据Gary的回答,我看了一下glogin.sql脚本 - 唯一的区别是'SET SQLPLUSCOMPATIBILITY 8.1.7'在工作客户端上存在但在失败的客户端上没有 - 但添加它并没有解决问题.

我也试过了

alter session set workarea_size_policy=manual;
alter session set hash_area_size=1048576000;
Run Code Online (Sandbox Code Playgroud)

alter session set sort_area_size=1048576000;
Run Code Online (Sandbox Code Playgroud)

无济于事:(

更新2

我设法找到了相同的行为,这次是与Oracle 8i后端交谈.在这种情况下,数据库是RW.这让我可以确认,正如我所怀疑的那样,不同的客户会产生不同的计划.但为什么????

看看'SHOW PARAMETERS'的输出,两个客户都报告了完全相同的设置!

sym*_*ean 0

不是真正的答案 - 但更多信息......

我们本地的 DBA 能够确认 16Gb (!) TEMP 表空间确实正在使用并且已被填满,但仅限于 Linux 客户端(我能够重新创建从 PHP 进行 oci8 调用时出现的错误)。在 sqlplus 客户端的情况下,我实际上使用完全相同的文件在两个客户端上运行查询(通过 scp 复制而不进行文本转换 - 所以行结尾是 CRLF - 即逐字节与在 Windows 客户端上运行的相同) 。

因此,唯一合理的解决方案是两个客户端堆栈导致不同的执行计划!

在负载很小的 DBMS 上几乎同时从两个客户端运行查询会得到相同的结果 - 这意味着两个客户端还为查询生成不同的 sqlid。

(而且 Oracle 也忽略了我的提示 - 我讨厌它这样做)。

Oracle 不应该这样做 - 即使它在将查询呈现给 DBMS 之前对其进行了一些内部修改(这将产生不同的 sqlid),所使用的客户端堆栈对于选择一个查询应该是完全透明的。执行计划 - 这应该只根据查询的内容和 DBMS 的状态而改变。

由于没有看到任何解释计划,问题变得很复杂 - 但是对于要使用这么多临时表空间的查询,它必须在过滤结果集之前执行非常丑陋的连接(至少部分是笛卡尔连接)。添加提示来覆盖它没有效果。因此,我通过将查询拆分为 2 个游标并使用 PL/SQL 进行嵌套查找来解决该问题。这是一个非常丑陋的解决方案,但它解决了我眼前的问题。幸运的是我只需要生成一个文本文件。

为了任何发现自己陷入类似困境的人的利益:

BEGIN

DECLARE
CURSOR query_outer IS
    SELECT some_primary_key, some_other_stuff
    FROM atable
    WHERE....

CURSOR query_details (p_some_pk) IS
    SELECT COUNT(*), SUM(avalue)
    FROM btable
    WHERE fk=p_some_pk
    AND....

FOR m IN query_outer
LOOP
    FOR n IN query_details(m.some_primary_key)
    LOOP
        dbms_out.put_line(....);
    END LOOP;
END LOOP;

END;
Run Code Online (Sandbox Code Playgroud)

我越用Oracle,就越讨厌它!