【发布时间】:2012-02-02 12:36:24
【问题描述】:
我尝试解决我的应用程序的性能问题。 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 的快速 - 从带有休眠功能的小型 Java 应用程序中快速运行 - 使用休眠的应用程序非常慢(> 100x 慢) - 绑定变量的值分别为 2 和 30(rownum 来自分页) - 休眠查询是上面的“形式”。视图中实际上大约有 20 列。
当前分析状态
- 查询计划显示当查询来自 SQlDeveloper 或“小型 Java 应用程序”时使用索引。
- 查询计划显示,如果查询来自休眠应用程序,则会执行全表扫描
- DB 跟踪仅显示两个差异:NLS 设置(来自 SQLDeveloper)和稍有不同的格式(空格)。其他一切似乎都一样...
版本
- 休眠:2.1.8
- jdbc 驱动:使用 ojdbc14、5 和 6。没有区别
- Oracle:10.2 和 11。没有区别
=> 我很高兴有人可能对这个问题提出任何提示。令我困扰的是数据库跟踪没有显示任何差异的事实......是的,看起来它与休眠有关。但是什么?如何检测?
为了完整起见,这里是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。
【问题讨论】:
-
我怀疑您在此处输入的查询中有错字,因为内部选择中有两个
where。where rownum子句实际上是在外部选择上吗? -
您说“view_user 有 ~ 2 个 mio 条目”。请定义“mio”。另外,view_user.state 的可能值是多少,每个可能值有多少行?最后,为 :1 和 :2 提供了哪些值?谢谢。
-
sry,mio 是百万。内部选择的完整返回集可能是完整视图 (view_user) 的 80% 左右,因为 "this.state=:1" 的值为 2 表示 :1。
-
:2 是 30。我更新了最初的问题描述。
-
是的,有。 state_id 是表的外键,其中 state_id 是主键
标签: performance oracle hibernate indexing