我必须使用 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 (?, ?, ..., ?) <100> - 必须创建解释计划
(b) select COL_1, COL_2, ..., COL_N from TAB_1 where COL_1 in (?, ?, ..., ?) <100> - 解释计划不会被创建,因为它已经存在于缓存中
(c) select COL_1, COL_2, ..., COL_N from TAB_1 where COL_1 in (?, ?, ..., ?) <120> - 应该创建解释计划(对于具有 120 个参数的查询没有解释计划) 但与 (a) 相比,它花费的时间更少,几乎与 (b) 相同,因此如果之前执行类似的查询,Oracle 可能可以更快地创建此计划
这是什么原因?