你好,我有一个查询到Oracle系统,其中涉及一个视图,该视图通过将TO_NUMBER()应用于表的主键来连接其他表。
如果我使用TOAD进行查询,查询速度非常快(1秒800字节)。如果我使用JDBC在Java程序中使用String literal(不是参数化查询)进行相同的查询,时间也很好。
但是如果我通过PreparedStatement使用参数化查询,查询需要1分钟来获取相同的寄存器。我知道使用常量值比使用参数产生不同的执行计划.但是如果我在视图的连接中删除TO_NUMBER函数,参数化查询也很快。
- 参数/ TO_NUMBER()联合是否阻止使用连接表的PK索引?
- 有没有解决这个问题的方法(我需要查询的参数和TO_NUMBER函数)?
P.D.为我糟糕的英语道歉
4条答案
按热度按时间rqenqsqc1#
在没有额外信息的情况下,我们只能假设一个索引没有被使用,而to_number()函数被应用于该列。如this SO question所示,类型转换可以阻止优化器使用索引。
一般而言:
to_number(id)
),优化器将无法使用该列的常规索引,WHERE trunc(col) = DATE '2009-08-27'
,应该使用:WHERE col >= DATE '2009-08-27' AND col < DATE '2009-08-28'
,而不是用途:suzh9iv82#
检查参数中传递的Java变量的数据类型是否与Oracle数据类型兼容。当通过与Oracle日期列进行比较的绑定变量传递Java TIMESTAMP时,我看到过类似的症状-文字字符串查询OK,PL/SQL中的测试用例(日期)绑定OK,Java代码w/ mismatch not OK。
[编辑]我认为你已经提供了一些额外的信息,因为最初的帖子。要了解在不同环境(Java和Toad)中查询的形式(绑定和字面量)略有不同的情况,最好的方法是在执行期间启用跟踪,并比较结果跟踪文件中的执行路径。这需要您能够访问数据库主机以检索文件。
jmp7cifd3#
检查以确保没有人设置属性oracle.jdbc.defaultNChar=true
有时候这样做是为了解决unicode问题,但这意味着所有列都被视为nvarchars。如果你有一个varchar列的索引,它不会被使用,因为oracle必须使用一个函数来转换字符编码。
bbmckpt74#
这实际上是一个与ORACLE服务器端配置有关的问题,如果origin是FORCE,只需将Cursor_Sharing更改为EXACT即可