高性能的 JDBC 批处理查询
Posted
技术标签:
【中文标题】高性能的 JDBC 批处理查询【英文标题】:JDBC batch query for high performance 【发布时间】:2012-04-08 20:08:33 【问题描述】:我想做批量查询数据库以获得高性能,例如基于不同customer_id查询的sql:
select order_id,
cost
from customer c
join order o using(id)
where c.id = ...
order by
我不确定如何使用 JDBC 语句来做到这一点。我知道我可以为此目的使用存储过程,但是如果我可以在 Java 应用程序而不是 SP 中编写 sql 会更好。 我将 DBCP 用于我的 Java 客户端和 mysql DB。
【问题讨论】:
“批量查询”到底是什么意思?您可以使用where c.id in (...)
获得多个客户。
我不知道您所说的“为客户提供多个结果集”是什么意思。
@a_horse_with_no_name 我的意思是一个客户的一个结果集,不要混合返回行。
【参考方案1】:
您的 SQL 语句是什么实际上并不重要(您可以使用数据库可以处理的尽可能多的嵌套连接)。下面是基本的 Java 示例(不是 DBCP)。对于非常相似的 DBCP 示例,您可以查看他们的example。
Connection connect = DriverManager.getConnection(YOUR_CONNECTION_STRING);
// Statements allow to issue SQL queries to the database
Statement statement = connect.createStatement();
ResultSet resultSet = statement.executeQuery("select order_id, cost
from customer c
join order o using(id)
where c.id = ...
order by");
【讨论】:
我想做批量查询,这意味着为一个数据库查询获取多个结果,sql语句如:select order_id,cost from customer c join order o using(id) where c.id = 123 order by ;select order_id, cost from customer c join order o using(id) where c.id = 456 order by; 您可以将编译为参数的任何 sql 语句提供给executeQuery()
BTW:在您的示例中,可以将 2 个查询合并为一个【参考方案2】:
JDBC Specification 4.0 描述了一种批量更新机制。因此,JDBC 中的批处理功能可用于插入或更新目的。这在规范的第 14 章中有描述。
AFAIK 没有选择批次的机制,可能是因为没有明显的需要,因为正如其他人所建议的那样,您可以通过正确构造查询来一次检索所需的所有行。
int[] ids = 1, 2, 3, 4 ;
StringBuilder sql = new StringBuilder();
sql.append("select jedi_name from jedi where id in(");
for (int i = 0; i < ids.length; i++)
sql.append("?");
if(i+1 < ids.length)
sql.append(",");
sql.append(")");
System.out.println(sql.toString());
try (Connection con = DriverManager.getConnection(...))
PreparedStatement stm = con.prepareStatement(sql.toString());
for(int i=0; i < ids.length; i++)
stm.setInt(i+1, ids[i]);
ResultSet rs = stm.executeQuery();
while (rs.next())
System.out.println(rs.getString("jedi_name"));
catch (SQLException e)
e.printStackTrace();
输出
select jedi_name from jedi where id in(?,?,?,?)
Luke, Obiwan, Yoda, Mace Windu
你有什么理由认为你需要一个像批处理选择语句这样的东西?
【讨论】:
我目前的理论是,对于选择(例如使用 ResultSet),它们会在您进行时“自动缓冲”接下来的几行,因此它们是免费“批量”选择的。 FWIW @rogerdpack 你的意思是fetchSize 属性吗?这可能有效,尽管文档指出这可能只是对数据库的提示。并非所有驱动程序都必须实现它。 嘿,就是这样,感谢您的链接!对于追随者,出现 Postgres 时,您还需要关闭自动提交(奇怪):***.com/questions/1468036/…以上是关于高性能的 JDBC 批处理查询的主要内容,如果未能解决你的问题,请参考以下文章