我的sql看起来像这样:
SELECT some_column FROM some_table WHERE some_column IN (v1, v2, v3, v4, ..., v100, v101, ... v1000, v1001, ... );
IN子句有时包含很多项目/ ID,如1000或更多。我不是一个SQL专家,有没有办法解决这个问题,因为这个查询的性能非常低? IN子句的一些替换?
更准确地说,价值来自方法:
public void slowQuery() {
List<Integer> ids = getIds();
String queryString = "SELECT some_column FROM some_table WHERE some_column IN :ids";
Query query = getSession().createQuery(queryString);
query.setParameter(ids, "ids");
....
}
public List<Integer> getIds() {
List<Integer> ids = new ArrayList<Integer>();
// run 4 queries to get data and put them into ids array
return ids;
}
答案 0 :(得分:1)
有两种方法可以解决这个问题,具体取决于Ids来自哪里。
如果Ids来自某个外部系统或非常复杂的过程,则将它们插入临时表中。然后修改您的查询以包括:
WHERE ID IN (SELECT id FROM temp)
如果Ids来自同一数据库中的选择,那么请避免将它们通过网络传输到您的客户端软件,只是为了让它们再次发回:
WHERE ID IN ( SELECT ...however you find them now... )
在上述两种情况下,您可能更喜欢使用INNER JOIN
而不是IN
列表。我更容易用IN
条款来解释,因为它更符合您现在的条件。
答案 1 :(得分:1)
首先,创建一个VARRAY类型:
create or replace TYPE the_list_type AS VARRAY (2000) OF INTEGER;
然后,创建一个存储过程,接受列表中的&#34;&#34;作为字符串参数,将列表转换为数组,然后使用以下类型的构造中的数组运行查询:
select * from x
from dual
where id in (select column_value from table(cast(list_var as the_list_type)));
将此作为返回参数写入引用游标。
现在,修改您的Java调用以调用此存储过程,将输入列表作为csv传递,并读取返回引用游标。
请参阅此示例,了解如何构建存储过程:
答案 2 :(得分:0)
尝试将IN
子句中的项目添加到表格,并将此表格加入some_table