gpt4 book ai didi

performance - 来自 Hibernate App 的查询不使用数据库索引

转载 作者:行者123 更新时间:2023-12-04 19:16:35 26 4
gpt4 key购买 nike

我尝试解决我的应用程序的性能问题。 hibernate 生成的查询格式如下:

select * 
from (
select this.a, this.b, this.state, this.id
from view_user this
where this.state=:1 order by this.a asc, this.b
)
where rownum <= :2

在哪里
  • id是主键
  • (a, b, id) 上有一个组合的唯一索引。
  • view_user 有大约 200 万个条目
  • view_user 对其他表执行一些进一步的连接

  • 问题

    上面的查询执行
    - 来自 SQLDeveloper 的快速
    - 从带有 hibernate 功能的小型 Java 应用程序中快速运行
    - 使用 hibernate 的应用程序非常慢(> 100x 慢)
    - 绑定(bind)变量的值分别为 2 和 30(rownum 来自分页)
    - hibernate 查询是上面的“形式”。 View 中实际上有大约 20 列。

    当前分析状态
  • 查询计划显示当查询来自 SQlDeveloper 或“小型 Java 应用程序”时使用索引。
  • 查询计划显示,如果查询来自 hibernate 应用
  • ,则执行全表扫描
  • DB 跟踪仅显示两个不同之处:NLS 设置(来自 SQLDeveloper)和稍有不同的格式(空格)。其他一切似乎都一样...

  • 版本
  • hibernate :2.1.8
  • jdbc 驱动:使用 ojdbc14、5 和 6。没有区别
  • Oracle:10.2 和 11。没有区别

  • => 对于有人可能对这个问题提出的每一个提示,我感到很高兴。令我困扰的是数据库跟踪没有显示任何差异的事实......是的,看起来它与 hibernate 有关。但是什么?如何检测?

    为了完整起见,这里是 hibernate 查询(来自日志):
    Select * from ( 
    select this.USER_ID as USER_ID0_, this.CLIENT_ID as CLIENT_ID0_,
    this.USER_NAME as USER_NAME0_, this.USER_FIRST_NAME as USER_FIR5_0_, this.USER_REMARKS as
    USER_REM6_0_, this.USER_LOGIN_ID as USER_LOG7_0_, this.USER_TITLE as USER_TITLE0_,
    this.user_language_code as user_lan9_0_, this.USER_SEX as USER_SEX0_,
    this.USER_BIRTH_DATE as USER_BI11_0_, this.USER_TELEPHONE as USER_TE12_0_,
    this.USER_TELEFAX as USER_TE13_0_, this.USER_MOBILE as USER_MO14_0_,
    this.USER_EMAIL as USER_EMAIL0_, this.USER_ADDRESSLINE1 as USER_AD16_0_,
    this.USER_ADDRESSLINE2 as USER_AD17_0_, this.USER_POSTALCODE as USER_PO18_0_,
    this.USER_CITY as USER_CITY0_, this.USER_COUNTRY_CD as USER_CO20_0_,
    this.USER_COUNTRY_NAME as USER_CO21_0_, this.USER_STATE_ID as USER_ST24_0_,
    this.USER_STATE as USER_STATE0_, this.USER_TEMP_COLL_ID as USER_TE26_0_,
    this.USER_TEMP_COLL_NAME as USER_TE27_0_, this.UNIT_ID as UNIT_ID0_,
    this.CLIENT_NAME as CLIENT_38_0_, this.PROFILE_EXTID as PROFILE39_0_
    from VIEW_USER this
    where this.USER_STATE_ID=:1 order by this.USER_NAME asc, this.USER_FIRST_NAME asc
    )
    where rownum <= :2

    唯一索引超过 user_name、user_first_name、user_id。

    最佳答案

    我遇到过类似的情况,所以这可能与您有关。

    JDBC 驱动程序正在将您的参数更改为 unicode,因此 varchar变成 nvarchar当它到达数据库时。如果幸运的话,SQL 2008 SP1 会捕捉到这一点并将其转换回来。但 SQL 2000 和 SQL 2005 不会,查询优化器将执行全表扫描而忽略您的索引。

    您可以通过添加连接参数 sendStringParametersAsUnicode=FALSE 在 JDBC 层解决此问题。到您的连接字符串。

    关于performance - 来自 Hibernate App 的查询不使用数据库索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8729760/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com