2

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

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

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

4

1 回答 1

1

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

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

以下是解决此问题的一些想法:

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

强制硬解析 有几种方法可以强制 Oracle 对每个查询进行硬解析。一种方法是在查询中的一个表上使用 NO_INVALIDATE=>FALSE 调用 DBMS_STATS。

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

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

于 2013-07-30T18:50:10.353 回答