在Java中通过JDBC查询速度慢,但在其他系统(TOAD)中则不然

问题描述 投票:0回答:4

您好,我有一个对 Oracle 系统的查询,其中涉及一个视图,该视图通过将 TO_NUMBER() 应用于表主键来连接其他表。

如果我使用 TOAD 进行查询,查询速度非常快(800 个寄存器 1 秒)。如果我在 java 程序中通过 JDBC 使用字符串文字(不是参数化查询)执行相同的查询,时间也很好。

但是,如果我通过PreparedStatement 使用参数化查询,则查询需要 1 分钟才能获取相同的寄存器。我知道使用常量值会比使用参数产生不同的执行计划...但是如果我删除视图连接中的 TO_NUMBER 函数,参数化查询也会很快。

  • 参数 / TO_NUMBER() 联合是否阻止使用连接表的 PK 索引?
  • 有解决方法来解决这个问题吗(我需要查询上的参数以及 TO_NUMBER 函数)?

P.D.抱歉我的英语不好

java performance oracle jdbc
4个回答
2
投票

如果没有其他信息,我们只能假设索引没有与应用于该列的 to_number() 函数一起使用。如这个SO问题所示,类型转换可以阻止优化器使用索引。

总体来说:

  • 当您向列添加函数时(即:
    to_number(id)
    ),优化器将无法使用该列上的常规索引,
  • 如果可能,您应该使用原始色谱柱。例如:您应该使用:而不是
    WHERE trunc(col) = DATE '2009-08-27'
    WHERE col >= DATE '2009-08-27' AND col < DATE '2009-08-28'
  • 如果您确实必须将函数应用于列,则可以使用基于函数的索引

2
投票

检查参数中传入的Java变量的数据类型是否与Oracle数据类型兼容。当通过与 Oracle DATE 列进行比较的绑定变量传递 Java TIMESTAMP 时,我看到了与您类似的症状 - 文字字符串查询正常,PL/SQL 中的测试用例与(日期)绑定正常,Java 代码与不匹配不正常。

[编辑] 我认为自最初发布以来您已经提供了一些附加信息。了解来自不同环境(Java 与 Toad)的查询的稍微不同形式(绑定与文字)所发生的情况的最佳方法是在执行期间启用跟踪,并比较生成的跟踪文件中的执行路径。这将要求您有权访问数据库主机才能检索文件。

  • 在 Toad 中,打开交互式 SQL 窗口(我不使用 Toad,但我确定 你会明白我的意思)和 发出 SQL 命令“alter session 设置 sql_trace=true"
  • 运行您的查询 - 这将是一个很好的选择 向查询添加评论的想法 例如“/* 带有文字的蟾蜍 */”
  • 对于Java测试,构建一个测试用例 发出“更改会话...” 语句,然后运行查询。 再次,向查询添加注释 将其识别为来自 Java 测试。
  • 不用担心转动描边 关闭 - 当 会话断开,并且在某些情况下 情况下的断开方法 最好停止跟踪。
  • 找出跟踪文件的位置 数据库主机是通过“选择 来自 v$parameter 的值,其中名称 就像'user_dump_dest'“
  • 通过搜索找到 .trc 文件 查询注释字符串
  • 使用操作系统中的 TKPROF 实用程序 命令行来处理跟踪 文件 - ” tkprof 文件名.trc tkprof 文件名.out“
  • 检查/发布执行路径并 你看到的时间。

0
投票

检查以确保有人没有设置属性 oracle.jdbc.defaultNChar=true

有时这样做是为了解决 unicode 问题,但这意味着所有列都被视为 nvarchar。如果你在 varchar 列上有索引,则不会使用它,因为 oracle 必须使用函数来转换字符编码。


0
投票

这实际上是一个与 ORACLE 服务器端配置相关的问题,如果 origin 是 FORCE,只需将 Cursor_Sharing 更改为 EXACT

© www.soinside.com 2019 - 2024. All rights reserved.