【问题标题】:ScalaQuery's query/queryNA several times slower than JDBC?ScalaQuery 的 query/queryNA 比 JDBC 慢几倍?
【发布时间】:2011-10-07 07:48:50
【问题描述】:

在以下多个查询的性能测试中,这段定时的 JDBC 代码需要 500-600ms:

      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 时,时间会变为 >2s:

      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 是建议的解决方法。

【问题讨论】:

  • 如果这实际上是您正在运行的代码,您可能需要确保,在您的第一个示例中,HotSpot 不只是丢弃您的循环,即它确实在执行语句1000 次。
  • 不要扔掉它 - executeQuery 有副作用。

标签: scalaquery


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-08
    • 2021-04-12
    • 1970-01-01
    • 2014-09-12
    • 2011-06-25
    • 1970-01-01
    • 2015-02-20
    • 2014-01-21
    相关资源
    最近更新 更多