【问题标题】:unable to extend temp segment by 128 in tablespace TEMP无法在表空间 TEMP 中将临时段扩展 128
【发布时间】:2017-07-01 13:48:10
【问题描述】:

我正在尝试在 Oracle 中执行以下查询:

SELECT DISTINCT
   t4.s_studentreference "Student ID",
  t3.p_surname "Surname",
  t3.p_forenames "Forenames",
t1.m_reference "Course",
 t2.e_name "Enrolment Name"
 FROM student t4,
  person t3,
  enrolment t2,
  course t1
WHERE t4.s_id(+) =t3.p_id
AND (t2.e_student=t3.p_id)
AND (t2.e_course =t1.m_id)
AND (t1.m_reference LIKE 'LL563%15')
OR (t1.m_reference LIKE 'LL562%15')
OR (t1.m_reference LIKE 'LL563%16')
OR (t1.m_reference LIKE 'LL562%16')

但是,我收到以下错误:

ORA-01652: unable to extend temp segment by 128 in tablespace TEMP
01652. 00000 -  "unable to extend temp segment by %s in tablespace %s"
*Cause:    Failed to allocate an extent of the required number of blocks for
           a temporary segment in the tablespace indicated.
*Action:   Use ALTER TABLESPACE ADD DATAFILE statement to add one or more
           files to the tablespace indicated.

我使用下面的查询来查找临时段空间:

    select inst_id, tablespace_name, total_blocks, used_blocks, free_blocks
 from gv$sort_segment;

给:

INST_ID, TABLESPACE_NAME, TOTAL_BLOCKS, USED_BLOCKS, FREE_BLOCKS
1           TEMP           3199872       15360         3184512

知道怎么解决吗?

谢谢, 阿鲁娜

【问题讨论】:

  • 我认为这个问题在 dba.stackexchange.com 上可能会得到更好的回答。
  • 错误信息具体告诉你要采取什么行动。
  • @OldProgrammer,这是一个很好的例子,为什么有时从 oracle 错误消息中获取“行动”建议并不总是最好的行动方案:)

标签: oracle oracle-sqldeveloper temp segment tablespace


【解决方案1】:

虽然对此的标准答案是让您的 DBA 扩展 TEMP 表空间,但我认为问题在于您的查询。

具体来说,您编写 WHERE 子句谓词的方式。我怀疑前三个谓词是您的连接谓词,后四个应该限制课程表中要连接的行。

但是,发生的事情是首先计算前四个谓词(因为 AND 优先于 OR),我怀疑这会导致您的连接出现一些问题 - 可能是一些意外的交叉连接,这可能是意外炸毁了您的 TEMP 表空间。

为防止这种情况发生,您有两种可能的解决方案:

1.在正确的位置用括号阐明您的 AND/OR 逻辑:

SELECT DISTINCT
       t4.s_studentreference "Student ID",
       t3.p_surname "Surname",
       t3.p_forenames "Forenames",
       t1.m_reference "Course",
       t2.e_name "Enrolment Name"
FROM   student t4,
       person t3,
       enrolment t2,
       course t1
WHERE  t4.s_id(+) = t3.p_id
AND    t2.e_student = t3.p_id
AND    t2.e_course = t1.m_id
AND    (t1.m_reference LIKE 'LL563%15'
        OR t1.m_reference LIKE 'LL562%15'
        OR t1.m_reference LIKE 'LL563%16'
        OR t1.m_reference LIKE 'LL562%16');

上面将所有的 OR 语句组合在一起,然后将它们与其他谓词相结合。

2。使用 ANSI 连接语法并将搜索谓词与连接谓词分开:

SELECT DISTINCT
       t4.s_studentreference "Student ID",
       t3.p_surname "Surname",
       t3.p_forenames "Forenames",
       t1.m_reference "Course",
       t2.e_name "Enrolment Name"
FROM   student t4,
       RIGHT OUTER JOIN person t3 ON t4.s_id = t3.p_id
       INNER JOIN enrolment t2 ON t3.p_id = t2.e_student 
       INNER JOIN course t1 ON t2.e_course = t1.m_id
WHERE  t1.m_reference LIKE 'LL563%15'
OR     t1.m_reference LIKE 'LL562%15'
OR     t1.m_reference LIKE 'LL563%16'
OR     t1.m_reference LIKE 'LL562%16';

当然,当您在 where 子句中同时使用 AND 和 OR 时,后者并不排除在正确位置使用括号...

选项 2 将是我的首选解决方案 - ANSI 连接语法确实是当今编写 SQL 时的前进方向。

【讨论】:

  • 感谢 Boneist。:)
  • 我实际上经常看到这种情况,人们将 Oracle 外连接语法转换为 ANSI 外连接语法,并且使连接和谓词混淆或放错位置。他们最终得到的是“加入常量”,虽然在语法上有效,但在语义上通常不是必需的。
  • @BobC 是的;我对 ANSI 外连接语法有点警惕,我通常必须敲出一个测试用例来证明它按我希望的方式工作!或者我外部加入子查询 *{;-)
猜你喜欢
  • 2018-11-30
  • 1970-01-01
  • 1970-01-01
  • 2021-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多