如何在使用大量列入的项目/ ID时替换IN子句?

时间:2014-08-19 05:41:43

标签: sql oracle oracle11g

我的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;
}

3 个答案:

答案 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传递,并读取返回引用游标。

请参阅此示例,了解如何构建存储过程:

https://community.oracle.com/thread/1071713?tstart=0

答案 2 :(得分:0)

尝试将IN子句中的项目添加到表格,并将此表格加入some_table