Tim*_*m B 6 java sybase prepared-statement functional-index
我在sybase表上创建了一个功能索引.
create index acadress_codpost_lower on acadress(LOWER(l5_codpost))
Run Code Online (Sandbox Code Playgroud)
然后我运行一个使用索引的复杂查询.没有索引需要17.086秒.索引需要0.076秒.
我从两个不同的SQL客户端以及开发和预生成的Sybase服务器上运行它.在所有情况下,我都看到了索引的加速度.
但是当我们从Java运行一个相同的查询时(我知道它是相同的,因为我已经记录了生成的SQL并直接在SQL客户端中使用它),那么性能与我们添加索引之前完全相同.
从ACE和SQuirreL运行而不是从Java运行时,相同的SQL查询可能有什么原因可以使用索引?
我的第一个想法是,Sybase可能正在缓存Prepared Statements的执行计划,而不是使用索引.我们已经尝试多次重启Java服务器(其他服务使用Sybase服务器因此更难反弹)并且没有任何区别.
另一种可能性是我们使用的是非常旧版本的Sybase驱动程序:
jConnect (TM) for JDBC(TM)/7.00(Build 26502)/P/EBF17993/JDK16/Thu Jun 3 3:09:09 2010
Run Code Online (Sandbox Code Playgroud)
此版本的JConnect可能不支持功能索引吗?
有谁知道这些理论中的任何一个是否正确,或者是否还有其他我错过的东西?
在过去的一周左右的时间里,我一直在断断续续地研究这个问题,虽然我仍然没有明确的答案,但我确实有一个合理的理论。
我尝试了评论中的建议,感谢他们,如果我有疑问,我能够将原因缩小到一个更改:
"where LOWER(aca.l5_codpost) like '"+StringEscapeUtils.escapeSql("NG179GT".toLowerCase())+"'"
Run Code Online (Sandbox Code Playgroud)
然后查询使用索引并且返回速度极快。
另一方面,如果我有:
where LOWER(aca.l5_codpost) like :postcode
query.setString("postcode", "NG179GT".toLowerCase());
Run Code Online (Sandbox Code Playgroud)
那么它不使用索引。
理论上,Sybase 正在优化查询计划,但没有有关 内容的信息:postcode,因此它没有使用索引。一旦知道内容,它就不会重新编译查询,因此它永远不会使用索引。
我尝试过强制使用索引(index acadress_codpost_lower),但这没有什么区别。
我已经尝试过set forceplan off,set literal_autoparam off但都没有任何区别。
我能发现改变行为的唯一方法是将选项直接嵌入到查询计划中,而不是将其作为参数。
因此,解决方法是将参数嵌入到查询字符串中,尽管我仍然想知道实际发生的情况并正确解决问题。
| 归档时间: |
|
| 查看次数: |
331 次 |
| 最近记录: |