【发布时间】:2010-12-15 20:36:19
【问题描述】:
我必须使用 Hibernate 并从 Oracle 检索数据,但问题是传递给查询的参数数量并不总是相同。
为简单起见,让我们考虑以下查询:
从 TAB_1 中选择 COL_1、COL_2、...、COL_N,其中 COL_1 在 (?, ?, ... ?) 中
传递给 in 子句的参数数量在 1 到 500 之间。如果数量在 1 到 50 左右,它的工作速度非常快,但是对于 200,它需要几秒钟来执行查询(解析、创建解释计划、执行查询)。索引已创建和使用 - 已检查。
查询是动态创建的,所以我使用 Hibernate Criteria API。对于第一个查询(具有 > 100 个参数),它需要 3-5 秒,但对于下一个查询,它的工作速度更快(即使参数数量不同)。我想改进第一个查询的响应时间。假设必须使用 Hibernate,在这种情况下我该怎么办?
我想删除这个动态查询,在 xml 文件中创建一些静态查询作为命名查询(在这种情况下,这些查询将在开始时预编译)例如
1) 参数个数少于50个时查询一次。
在这种情况下,如果我们有 30 个参数,查询将如下所示:
从 TAB_1 中选择 COL_1、COL_2、...、COL_N,其中 COL_1 在 (PAR_1, PAR_2, ..., PAR_30, -1, -1 , ..., -1 ?)
2) 如果数字在 50 到 100 之间,则为第二个。
问题在于使用命名查询和 HQL 并不是那么简单(在 JDBC 中它会很简单)。在 HQL 中,我们只传递了一个列表,并且我们没有在该列表中指定多个参数,即实际上只有一个查询
'from Person where id in (:person_list)'
myQuery.setParameterList("person_list", myList)
有没有办法解决这个问题?
顺便说一句,我认为解释计划是针对每个新查询执行的,例如:
(a) select COL_1, COL_2, ..., COL_N from TAB_1 where COL_1 in (?, ?, ..., ?) - 必须创建解释计划
(b) select COL_1, COL_2, ..., COL_N from TAB_1 where COL_1 in (?, ?, ..., ?) - 解释计划不会被创建,因为它已经存在于缓存中
(c) select COL_1, COL_2, ..., COL_N from TAB_1 where COL_1 in (?, ?, ..., ?) - 应该创建解释计划(查询没有解释计划有 120 个参数),但与 (a) 相比,它花费的时间更少,与 (b) 几乎相同,因此如果之前执行类似的查询,Oracle 可能可以更快地创建此计划
这是什么原因?
【问题讨论】:
-
select COL_1, COL_2, ..., COL_N from TAB_1 其中 COL_1 in (?, ?, ..., ?) - 是多个参数
标签: performance oracle hibernate dynamicquery