ScalaQuery的query/queryNA比JDBC慢几倍?

发布于 2024-11-25 00:46:19 字数 876 浏览 5 评论 0原文

在下面的许多查询的性能测试中,这个定时的 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 作为解决方法。

In the following performance tests of many queries, this timed JDBC code takes 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()
        }
      }

However, when using ScalaQuery, the time goes to >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)
        }
      }

After debugging with server logs, this turns out to be due to the fact that the PreparedStatements are being repeatedly prepared and not reused.

This is in fact a performance issue that we've been hitting in our application code, so we're wondering if we're missing something regarding how to reuse prepared statements properly in ScalaQuery, or if dropping down to JDBC is the suggested workaround.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

如此安好 2024-12-02 00:46:19

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

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

Got an answer from the scalaquery mailing list. This is just how ScalaQuery is designed - it assumes that you're something that provides statement pooling underneath:

Nowadays ScalaQuery always requests a new PreparedStatement from the Connection. There used to be a cache for PreparedStatements in early versions but I removed it because there are already good solutions for this problem. Every decent connection pool should have an option for PreparedStatement pooling. If you're using a Java EE server, it should have an integrated connection pool. For standalone applications, you can use something like http://sourceforge.net/projects/c3p0/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文