我正在Java循环中执行一个简单的“select”查询,如下所示。列表的大小可以增长到10000+。如何提高查询速度?任何示例或建议表示赞赏。谢谢。
请注意我需要检索该表的每一列中的所有数据,这就是使用星号(*)的原因。
List<String> valueList = ....
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
conn = DriverManager.getConnection(dbURL, dbUsername, dbPassword);
for (int m = 0; m < valueList.size() ; m++) {
String sql = "SELECT * FROM WORKSHEET WHERE " + sheetId + " = '" +
valueList.get(m) + "'";
ps = conn.prepareStatement(sql);
rs = ps.executeQuery();
// retreive data....
}
}
编辑:最后,有几种方法可以加快查询速度。我正在使用第二种方式,因为它将来会阻止ORA-04031错误。
答案 0 :(得分:6)
尝试提高速度时需要考虑两件事:
要走的路是使用SQL类型。这是PL / SQL中的一个例子。您可以在Java中使用相同的原则。
首先创建一个包含一万个sheetId的表:
SQL> create table worksheet (sheetid)
2 as
3 select level
4 from dual
5 connect by level <= 10000
6 /
Table created.
创建SQL类型:
SQL> create type mynumbers is table of number;
2 /
Type created.
在您的代码中,使用“valuelist”中的值填充SQL类型的实例,并使用TABLE运算符将类型转换为表值:
SQL> declare
2 valuelist mynumbers := mynumbers(23,124,987,6123,8923,1,7139);
3 begin
4 for r in
5 ( select ws.sheetid
6 from worksheet ws
7 , table(valuelist) vl
8 where ws.sheetid = vl.column_value
9 )
10 loop
11 dbms_output.put_line(r.sheetid);
12 end loop;
13 end;
14 /
1
23
124
987
6123
7139
8923
PL/SQL procedure successfully completed.
现在,共享池中只有一个SQL,只有一个执行此查询,而不是数千个。
答案 1 :(得分:4)
时间主要用于准备和执行查询。
如果您运行一个返回所有结果的查询,那么事情会更快。
即:
String where = "(1=0) "
// first build the where string
for (int m = 0; m < valueList.size() ; m++ ) {
where = where + " OR (" + sheetId + " = '" + valueList.get(m) + "'";
}
// then run a single query
sql = "SELECT * FROM WORKSHEET WHERE " + where;
ps = conn.prepareStatement(sql);
rs = ps.executeQuery();
// retrieve and handle data. ....
答案 2 :(得分:3)
您必须使用IN语句准备sql查询,然后只执行一次查询...
答案 3 :(得分:2)
以下是其他一些想法。
创建临时表并插入(10k)列表项。然后执行到主表的连接(1个查询)并获得结果。
创建一个存储过程,将项目列表(通过嵌套表格)作为输入,并通过out参数返回结果集。
我会选择选项1.因为它对我来说更直接,而且可能更快。但是你需要注意并发会话等。不确定你想如何处理多个会话(他们是否会共享这些数据,他们是否会有单独的数据列表?)。
无论如何要考虑的事情。
答案 4 :(得分:1)
Oracle IN
子句中最多可以包含1000个参数。因此,如果您使用预准备语句,您将减少1000倍的迭代次数。只需将列表拆分为1000个元素。
答案 5 :(得分:1)
你可以试试条款:sheetId IN ('1', '2', '3', '4')
请确保列sheetId
有一个索引键。
答案 6 :(得分:0)
我不知道这是否会有所改进,但您可以尝试选择所有记录,并在sheetId
匹配时检查您的Java代码。这是你应该知道什么是更好的东西。
答案 7 :(得分:0)
这是一个小问题,但如果要动态构造查询(不使用绑定变量),则应使用createStatement,而不是prepareStatement。您不需要使用prepareStatement进行少量开销。