【问题标题】:Oracle sql does not release space from temp when executing finishes执行完成时,Oracle sql 不会从 temp 释放空间
【发布时间】:2018-06-11 10:56:02
【问题描述】:

有一张表(比如说 TKubra),里面有 2.255.478 条记录。

还有这样的查询:

select * 
  from kubra.tkubra 
  where ckubra is null 
  order by c1kubra asc;

ckubra 没有空记录。它有 3000 条 id 记录,其余的有空格字符。

ckubra 有索引,但是当语句执行时,它会进行全表扫描,其成本为 258.794。 结果正常返回null。

语句执行时会消耗临时表空间空间,完成后不释放空间。

这是什么原因?

这是临时表空间使用的查询和结果:

【问题讨论】:

  • 您是如何以及在哪里看到临时空间被消耗和保留的?请edit your question 表明这一点。预计会进行全表扫描,但这似乎并不是您真正感兴趣的。

标签: oracle sorting null temporary


【解决方案1】:

Oracle 不在普通(BTree)索引中存储有关 NULL 值的信息。因此,当您使用WHERE CKUBRA IS NULL 之类的条件进行查询时,数据库引擎必须执行全表扫描才能生成答案。

但是,位图索引确实存储 NULL 值,因此如果您希望能够使用索引来查找 NULL 值,您可以在适当的字段上创建位图索引,如下所示:

CREATE BITMAP INDEX KUBRA.TKUBRA_2
  ON KUBRA.TKUBRA(CKUBRA);

创建索引后,请记住收集表的统计信息:

BEGIN
  DBMS_STATS.GATHER_TABLE_STATS('KUBRA', 'TKUBRA');
END;

可能允许数据库使用索引来查找 NULL 值 - 但请注意位图索引适用于低更新应用程序,例如数据仓库,并在事务表上使用(经常更新的)可能会导致性能问题。

不过,它还是可以玩的——你以后可以随时放下它。

祝你好运。

【讨论】:

  • 您能看看我刚刚添加到我的问题中的图片吗?当查询执行时,它的会话仍然存在,因此 temp 的使用仍然存在。
【解决方案2】:

直到所有行都返回,或者游标关闭,或者会话关闭,临时表空间才会被释放。

您确定所有这 19 个会话都真正完成了查询吗?看起来它返回了大量数据,这意味着应用程序可能需要一段时间才能检索所有行。

如果您在 SQL Developer 等 IDE 中运行查询,它通常只会返回前 N 行。您的 IDE 可能暗示查询已完成,但如果有更多行要接收,则还没有真正完成。

【讨论】:

  • 我公司使用京东 Oracle Web 应用程序。查询来自该应用程序。当我从 toad 或 sql developer 执行查询时,count(*) 的数量不会增加。它必须来自 Web 应用程序。如果查询更改为 select * from kubra.tkubra where ckubra=' ' (假设 75 个空格字符) order by c1kubra asc;在临时使用方面有什么不同吗?
  • BTW 查询完成但它的会话保持不变,因此它的临时使用保持不变。 Oracle 将该会话提供给其他 sql。我不明白为什么
  • @KübraÇakmak 所需的临时表空间将大致等于结果集的大小。我猜查询并没有真正“完成”。也许应用程序没有正确关闭游标。只是一个疯狂的猜测 - 这个查询很慢,因为它排序并返回大量数据,所以应用程序超时,但在异常处理程序中它忘记关闭连接。您可能需要调试或跟踪应用程序以准确了解发生了什么。
  • 谢谢@JonHeller,我会看的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多