【问题标题】:PreparedStatement and ORA-01652( unable to extend temp segment)PreparedStatement 和 ORA-01652(无法扩展临时段)
【发布时间】:2013-07-29 16:37:13
【问题描述】:

我有一个非常庞大的查询。它相当大,所以我不会在这里发布(它有 6 级嵌套查询,带有排序和分组)。查询有 2 个通过 PreparedStatement.setString(index, value) 传递给它的参数。当我通过 SQL Developer 执行查询时(手动将查询参数替换为实际值),查询运行大约 10 秒并返回大约 15000 行。但是,当我尝试使用带有变量的 PreparedStament 通过 java 程序运行它时,它会以ORA-01652(unable to extend temp segment) 失败。我尝试使用 java 程序中的简单语句 - 它工作正常。此外,当我使用不带变量的preparedStatement(不要使用setString(),而是手动指定参数)时,它也可以正常工作。

所以,我怀疑问题出在 PreparedStatemnt 参数中。

该参数的机制是如何工作的?为什么简单的语句可以正常工作,但准备好的语句却失败了?

【问题讨论】:

  • 您使用的是什么版本的 Oracle?优化器处理绑定变量的方式在 10 到 11 之间发生了显着变化。
  • 做一个“解释计划”看看发生了什么:stackoverflow.com/questions/4376329/…
  • 我怀疑 jonearles 是对的……在 SQL Developer 中执行的解释计划(尽管对排除某些东西很有用)如果它在 10 秒内返回可能无济于事。 Java 中更有可能发生了一些时髦的事情。首先要检查的是您的查询是否相同...
  • 2 jonearles:我使用的是 oracle 10g
  • 对“oracle 变量绑定窥视”进行一些谷歌搜索这是一篇文章的链接。 dba-oracle.com/t_bind_variable_peeking_tips.htm 我的猜测是,oracle 正在使用不同的计划与准备好的语句和绑定参数。您可能需要向查询添加提示,以便它使用与使用文字运行查询时使用的相同索引等。您可以通过在 sqlplus 会话中使用变量来模拟与在您的 java 代码中所做的查询相同的问题。

标签: oracle jdbc prepared-statement


【解决方案1】:

您可能会遇到绑定变量窥视的问题。

对于同一个查询,根据实际绑定变量的不同,最佳计划可能会有很大的不同。在 10g 中,Oracle 基于使用的 first 绑定变量集构建执行计划。 11g 主要通过自适应游标共享解决了这个问题,该特性可以为不同的绑定变量创建多个计划。

这里有一些解决这个问题的想法:

使用文字 这并不总是像人们想象的那么糟糕。如果您的查询的好版本在 10 秒内运行,那么硬解析查询的开销将可以忽略不计。但是您可能需要小心避免 SQL 注入。

强制硬解析有几种方法可以force Oracle to hard-parse every query。一种方法是在查询中的一张表上使用 NO_INVALIDATE=>FALSE 调用 DBMS_STATS。

禁用绑定变量窥视/提示您可以通过删除相关直方图或使用 OldProgrammer 提供的链接中的参数之一来做到这一点。这将稳定您的计划,但不一定会选择正确的计划。您可能还需要使用提示来选择正确的计划。但是,您可能没有为每种输入组合制定正确的计划。

升级到 11g 这可能不是一个选择,但这个问题是开始计划升级的另一个好理由。

【讨论】:

    猜你喜欢
    • 2012-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-27
    相关资源
    最近更新 更多