【问题标题】:Why would Sybase not use a functional index?为什么 Sybase 不使用功能索引?
【发布时间】:2015-03-27 15:58:43
【问题描述】:

我在 sybase 表上创建了一个功能索引。

create index acadress_codpost_lower on acadress(LOWER(l5_codpost))

然后我运行一个使用索引的复杂查询。没有索引需要 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

此版本的 JConnect 是否可能不支持功能索引?

有谁知道这些理论中的任何一个是否正确,或者是否还有其他我遗漏的东西?

【问题讨论】:

  • 可能相关:statement cache 你有什么确切版本的 Sybase?查询是否相同? (只是猜测,语句缓存可能区分大小写)
  • 来自“其他”系统的查询与基于 Java 的查询的相同程度如何?准备好的语句也可能是问题所在,是否有任何值参数化?一个好的测试是提取从控制台运行的相同 SQL,并将其输入到 Java 的常规 JDBC 语句中,然后“按原样”运行。
  • 我对 Sybase 几乎一无所知,但是在 SQL Server 中,如果客户端具有与对象定义不匹配的某些 SET 选项,则查询优化器 won't consider 会在计算列和索引视图上建立索引.也许 Sybase 对基于函数的索引有一些类似的规则,而 ACE 使用的客户端选项与 Java 不同?
  • 感谢您的建议,明天早上我回到办公室时会仔细研究它们...

标签: java prepared-statement sybase functional-index


【解决方案1】:

在过去一周左右的时间里,我一直在断断续续地研究这个问题,虽然我仍然没有明确的答案,但我确实有一个合理的理论。

我尝试了 cmets 的建议,多亏了他们,如果我有疑问,我能够将原因缩小到单个更改:

"where LOWER(aca.l5_codpost) like '"+StringEscapeUtils.escapeSql("NG179GT".toLowerCase())+"'"

然后查询使用索引,返回速度极快。

另一方面,如果我有:

where LOWER(aca.l5_codpost) like :postcode

query.setString("postcode", "NG179GT".toLowerCase());

那么它不使用索引。

理论上,Sybase 正在优化查询计划,没有关于:postcode 内容的信息,因此它没有使用索引。一旦知道内容,它就不会重新编译查询,因此它永远不会使用索引。

我尝试使用 (index acadress_codpost_lower) 强制索引,但没有任何区别。

我试过set forceplan offset literal_autoparam off 都没有任何区别。

我能发现改变行为的唯一方法是将选项直接嵌入到查询计划中,而不是将其作为参数。

因此,解决方法是将参数嵌入到查询字符串中,尽管我仍然想知道实际发生了什么并正确解决问题。

【讨论】:

    猜你喜欢
    • 2018-12-31
    • 1970-01-01
    • 2022-10-15
    • 1970-01-01
    • 2015-04-25
    • 1970-01-01
    • 1970-01-01
    • 2020-08-13
    • 2019-02-08
    相关资源
    最近更新 更多