2011-07-17 32 views
1

在许多查询以下性能测试中,这个定时JDBC代码需要500-600ms:ScalaQuery的query/queryNA比JDBC慢数倍?

 val ids = queryNA[String]("select id from account limit 1000").list 
     val stmt = session.conn.prepareStatement("select * from account where id = ?") 
     debug.time() { 
     for (id <- ids) { 
      stmt.setString(1, id) 
      stmt.executeQuery().next() 
     } 
     } 

然而,在使用时ScalaQuery的时间去> 2秒:

 val ids = queryNA[String]("select id from account limit 1000").list 
     implicit val gr = GetResult(r =>()) 
     val q = query[String,Unit]("select * from account where id = ?") 
     debug.time() { 
     for (id <- ids) { 
      q.first(id) 
     } 
     } 

与调试后,服务器日志,原来这是由于PreparedStatements正在重复准备并且未被重用。

这实际上是我们在应用程序代码中遇到的一个性能问题,所以我们想知道如果我们错过了关于如何在ScalaQuery中正确地重复使用预准备语句的问题,或者如果下降到JDBC是建议的解决方法。

+0

如果这实际上是你正在运行的代码,你可能想要确保的是,在你的第一个例子,热点不只是扔掉你的循环,即它确实在执行1000次声明。 – ig0774

+0

不会抛弃它 - executeQuery有副作用。 – Yang

回答

1

从scalaquery邮件列表中得到答案。这就是ScalaQuery的设计方式 - 它假设你是在下面提供语句池的东西:

如今ScalaQuery总是从Connection请求一个新的PreparedStatement。在早期版本中曾经有PreparedStatements的缓存,但我删除了它,因为这个问题已经有很好的解决方案。每个像样的连接池都应该有一个PreparedStatement池的选项。如果您使用的是Java EE服务器,则应该有一个集成的连接池。对于独立的应用程序,你可以使用像http://sourceforge.net/projects/c3p0/